2012-03-22 20 views
7

no puedo averiguar el bloque adecuado inicializar¿Cómo inicializar la clase en bloque en Ruby?

class Foo 
    attr_accessor :bar 
end 

obj = Foo.new do |a| 
    a.bar = "baz" 
end 

puts obj.bar 

esperar "Baz" en lugar de obtener nula

¿Cuál es el encantamiento adecuado para inicializadores de clase en el bloque de rubí?

+0

El 'attr_accessor' no puede funcionar en esa forma y nunca se llama al bloque. –

+0

Gracias, tienes razón al respecto, lo arreglé para que sea código "funcional" ahora – Doug

+0

Correcto, entiendo que no se llama (lo que explica por qué no funciona). Me gusta la idea de "tocar" a continuación, ya que me permite usar herramientas como FactoryGirl (que requieren inicializadores predeterminados) sin tener que anular las nuevas. – Doug

Respuesta

9

Inténtelo de nuevo:

class Foo 
    attr_accessor :bar 
end 

obj = Foo.new.tap do |a| 
    a.bar = "baz" 
end 

puts obj.bar 
+0

Eso no es lo mismo. Además, debería generar un 'NameError'. –

+0

Es la mejor manera sin agregar nuevas formas para que los usuarios tengan que leer la documentación. – Reactormonk

+0

Estoy de acuerdo. –

2

No creo que new tenga un bloque. Nunca lo vi en ningún lado. ¿Por qué quieres inicializar en un bloque? Siempre se puede hacer obj = foo.new.tap do |a| ... Si realmente quiere un bloque

+0

No es que * no * tome un bloque, es feo. A pesar de esto, es un "idioma" comúnmente visto. –

+0

Oh, está bien. Bueno, he aprendido algo hoy – ksol

+0

¿Por qué es feo? Es un idioma común en otros idiomas que he usado, como C#. – Doug

0

realidad tiene un constructor para estos fines:

class Foo 
    attr_accessor :bar 

    def initialize(bar = "baz") 
    @bar = bar 
    end 

end 
+0

Tal vez debería realmente hacer de eso un parámetro. –

+0

Niklas, sí, eso sería mejor – Sergey

+0

No es común pasarlos como constrcuter. Solo mira un código ruby ​​en github – slashmili

29

Otra manera de hacer un inicializador bloque sería Escríbelo usted mismo uno:

class Foo 
    attr_accessor :bar 

    def initialize 
    yield self if block_given? 
    end 
end 

Y más tarde lo utilizan:

foo = Foo.new do |f| 
    f.bar = true 
end 

Mis dos centavos.

+0

sin duda esta es la mejor manera de inicializar una clase con un bloque. –

Cuestiones relacionadas