Czytam sekcję METAPROGRAMOWANIE z programowania Ruby 1.9 i mam problemy ze zrozumieniem tego, co się dzieje wewnętrznie między class_eval
/class_exec
vs. instance_eval
/instance_exec
.Ruby def i instance_eval vs. class_eval
Więc przede wszystkim, moje rozumienie jest def
dodaje metodę tabeli metoda self
(obiekt klasy):
class A
puts self # => A
def foo; 42; end # added to the method table of self, so becomes an instance method
end
A.new.foo # => 42
A jeśli używamy class_eval
, mamy ten sam problem:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
Ale jakoś w przypadku instance_eval
, rzeczy są różne:
A.instance_eval do
puts self # => A
def baz; 42; end # added to the method table of an anonymous
# singleton class of self, so becomes a class method
end
puts A.baz # => 42
s = 'string'
s.instance_eval do ... end # same behavior, so now def creates an instance method
Rozumiem różnicę funkcjonalną między class_eval
i instance_eval
.
Ale konteksty wewnątrz class_eval
i instance_eval
bloków wyglądać dokładnie tak samo do mnie - w szczególności self
punkty do tego samego obiektu, a local_variables
są takie same. Co więc dzieje się wewnątrz bloków (wewnętrznie), co powoduje, że def
działa inaczej?
Czy mogę przeczytać dokumentację? RDoc dla instance_eval i class_eval nie pomaga. Patrząc na źródło, wydaje się, że instance_eval tworzy obiekt klasy singleton, podczas gdy class_eval nie - ale czy ta różnica jest widoczna poza kodem C, na poziomie Rubinowym?
Hm, rozumiem - to ma sens. Czy istnieje sposób sprawdzenia tej "aktualnej klasy" w kodzie Ruby? –
Myślę, że w 'A.instance_eval', miałeś napisać' #defs tutaj przejdź do A's eigenclass'? Czy jestem w błędzie? –
To nie jest takie proste, opublikuję kilka istotnych linków w odpowiedzi –