tutorial - ruby wikipedia
Ruby: extiéndete (5)
En Ruby, entiendo la idea básica de extend
. Sin embargo, ¿qué está pasando en este segmento de código? Específicamente, ¿qué hace extend
? ¿Es solo una forma conveniente de convertir los métodos de instancia en métodos de clase? ¿Por qué lo haría de esta manera en lugar de especificar los métodos de clase desde el principio?
module Rake
include Test::Unit::Assertions
def run_tests # etc.
end
# what does the next line do?
extend self
end
En un módulo, self es la clase de módulo en sí. Así por ejemplo
puts self
devolverá Rake así que,
extend self
básicamente hace que los métodos de instancia definidos en Rake estén disponibles para que pueda hacer
Rake.run_tests
Es una forma conveniente de convertir los métodos de instancia en métodos de clase. Pero también puede usarlo como un singleton más eficiente .
Para evitar link rot, la publicación del blog de Chris Wanstrath vinculada por user83510 se vuelve a publicar a continuación (con su permiso). Aún así, nada es mejor que un original, así que use su enlace mientras siga funcionando.
→ singting singletons 18 de noviembre de 2008 Hay cosas que simplemente no entiendo. David Bowie, por ejemplo. O el Hemisferio Sur. Pero nada perturba mi mente como el Singleton de Ruby. Porque realmente, es totalmente innecesario.
Esto es lo que quieren que hagas con tu código:
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''
Pero eso es una locura Luchar contra el poder.
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''
¿Por qué no? La API es más conciso, el código es más fácil de probar, simular y resguardar, y aún es muy fácil convertirlo en una clase adecuada si surge la necesidad.
((derechos de autor debe diez chris wanstrath))
Para mí siempre ayuda pensar en extend
como include
dentro de la clase singleton (también conocida como meta o clase propia).
Probablemente sepa que los métodos definidos dentro de la clase singleton son básicamente métodos de clase:
module A
class << self
def x
puts ''x''
end
end
end
A.x #=> ''x''
Ahora que sabemos eso, extend
los métodos en el módulo dentro de la clase singleton y los expondremos como métodos de clase:
module A
class << self
include A
def x
puts ''x''
end
end
def y
puts ''y''
end
end
A.x #=> ''x''
A.y #=> ''y''
extend self
incluye todos los métodos de instancia existentes como métodos de módulo. Esto es equivalente a decir extend Rake
. También Rake
es un objeto de clase Module
.
Otra forma de lograr un comportamiento equivalente será:
module Rake
include Test::Unit::Assertions
def run_tests # etc.
end
end
Rake.extend(Rake)
Esto se puede usar para definir módulos autónomos con métodos privados.