115 votes

Ruby: s'étendre

En Ruby, je comprends l’idée de base de extend . Cependant, que se passe-t-il dans ce segment de code? Plus précisément, que font extend ? Est-ce simplement un moyen pratique de transformer les méthodes d'instance en méthodes de classe? Pourquoi voudriez-vous le faire de cette façon plutôt que de spécifier les méthodes de classe depuis le début?

 module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

  # what does the next line do?
  extend self
end
 

117voto

user83510 Points 3885

C'est un moyen pratique de transformer des méthodes d'instance en méthodes de classe. Mais vous pouvez également l'utiliser comme un singleton plus efficace .

30voto

ennuikiller Points 28005

Dans un module, self est la classe de module elle-même. Donc par exemple

 puts self
 

retournera Rake donc,

 extend self
 

rend fondamentalement les méthodes d'instance définies dans Rake disponibles, vous pouvez donc faire

 Rake.run_tests
 

24voto

Philipe Points 1838

Pour moi, il est toujours utile de penser à extend tant que include à l'intérieur de la classe singleton (également appelée classe méta ou classe propre).

Vous savez probablement que les méthodes définies dans la classe singleton sont essentiellement des méthodes de classe:

 module A
  class << self
    def x
      puts 'x'
    end
  end
end

A.x #=> 'x'
 

Maintenant que nous savons que, extend vont include les méthodes du module dans la classe singleton et les exposeront ainsi comme méthodes de classe:

 module A
  class << self
    include A

    def x
      puts 'x'
    end
  end

  def y
    puts 'y'
  end
end

A.x #=> 'x'
A.y #=> 'y'
 

16voto

forforf Points 415

Pour éviter la pourriture des liens, le blog de Chris Wanstrath lié par user83510 est reposté ci-dessous (avec sa permission). Toujours, rien ne vaut un original, d'utiliser son lien aussi longtemps qu'il continue à travailler.


→ singin' singletons 18 novembre 2008 Il y a des choses que je ne comprends pas. David Bowie, par exemple. Ou de l'Hémisphère Sud. Mais rien ne dépasse mon esprit comme le Rubis Singleton. Parce que vraiment, c'est totalement inutile.

Voici ce qu'ils veulent vous faire avec votre code:

require 'net/http'

# first you setup your singleton
class Cheat
  include Singleton

  def initialize
    @host = 'http://cheat.errtheblog.com/'
    @http = Net::HTTP.start(URI.parse(@host).host)
  end


  def sheet(name)
    @http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.instance.sheet 'migrations'
Cheat.instance.sheet 'yahoo_ceo'

Mais c'est fou. Lutter contre la puissance.

require 'net/http'

# here's how we roll
module Cheat
  extend self

  def host
    @host ||= 'http://cheat.errtheblog.com/'
  end

  def http
    @http ||= Net::HTTP.start(URI.parse(host).host)
  end

  def sheet(name)
    http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.sheet 'migrations'
Cheat.sheet 'singletons'

Tout pourquoi pas? L'API est plus concis, le code est plus facile à tester, en moquer, et le talon, et cela reste toujours très simple de convertir en un bon de classe en cas de nécessité.

(( le droit d'auteur devrait dix chris wanstrath ))

4voto

Sulabh Jain Points 187

extend self inclut toutes les méthodes d'instance existantes en tant que méthodes de module. Cela équivaut à dire extend Rake . De plus, Rake est un objet de la classe Module .

Un autre moyen d'obtenir un comportement équivalent sera:

 module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

end 

Rake.extend(Rake)
 

Ceci peut être utilisé pour définir des modules autonomes avec des méthodes privées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X