2010-02-18 20 views
17

Bir blok kapanıyorsa, bu kod neden çalışmıyor ve nasıl çalışır?Kapatma çalışmıyor

def R(arg) 
    Class.new do 
    def foo 
     puts arg 
    end 
    end 
end 

class A < R("Hello!") 
end 

A.new.foo #throws undefined local variable or method `arg' for #<A:0x2840538> 
+0

Can Eğer bir blok alır define_method ile def değiştirin, istediğiniz sonucu göreceksiniz hata mesajlarınızı görüyoruz – samoz

+0

Hata mesajı örnekte yorum altında. – yukas

+0

@Earlz, düzenleme için teşekkürler. – yukas

cevap

26

bloklar kapama ve argClass.new blok içinde gerçekten kullanılabilir.yeni bir kapsam oluşturduğundan, foo yönteminde kullanılamaz. dinamik sınıfı tanımlarsanız istediğiniz gibi

def R(arg) 
    Class.new do 
     define_method(:foo) do 
      puts arg 
     end 
    end 
end 

class A < R("Hello!") 
end 

A.new.foo # Prints: Hello! 
+0

Parametreleri alan bir yöntem nasıl tanımlanır? – Geo

+2

@Geo: Parametre alan bir blok kullanmak. Örneğin. define_method (: add_one) do | x | x + 1 sonu – sepp2k

5

, bunu değiştirebilirsiniz:

def R(arg) 
    c = Class.new 

    # Send the block through as a closure, not as an inline method 
    # definition which interprets variables always as local to the block. 
    c.send(:define_method, :foo) do 
    arg 
    end 

    c 
end 

class A < R("Hello!") 
end 

puts A.new.foo.inspect 
# => "Hello!"