2012-02-27 13 views
7

instance_eval zmiana metoda siebie w swoim bloku, np:Jak zmienić self w bloku takim jak metoda instance_eval?

class D; end 
d = D.new 
d.instance_eval do 
    puts self # print something like #<D:0x8a6d9f4>, not 'main'! 
end 

Jeśli zdefiniujemy metodę Nas (lub jakiekolwiek inne metody (inne niż instance_eval), który pobiera blok), gdy druk siebie, będziemy mieli „głównym ”, który różni się od instance_eval method.eg:

[1].each do |e| 
    puts self # print 'main' 
end 

jaki sposób można zdefiniować metodę (która przyjmuje blok) jak instance_eval? Z góry dzięki.

+0

Co chcesz osiągnąć? – megas

+0

Nie sądzę, że można robić, co się chce. Pewnie dlatego, że byłoby zbyt zagmatwane, gdybyś mógł zmienić siebie samego. –

Odpowiedz

7

można napisać metodę, która akceptuje argumentu proc, a następnie przekazać to jako argument do instance_eval proc.

class Foo 
    def bar(&b) 
    # Do something here first. 
    instance_eval &b 
    # Do something else here afterward, call it again, etc. 
    end 
end 

Foo.new.bar {puts self}

Plony

#<Foo:0x100329f00> 
+0

Rozumiem, co masz na myśli, ale nie rozwiązałeś mojego problemu. Chcę zdefiniować metodę taką jak instance_eval zamiast using instance_eval. Chcę, aby wdrożenie nie było opakowaniem. Dziękuję wam wszystkim! – gaols

+1

Musisz więc dokładniej określić, co chcesz osiągnąć. Jeśli po prostu potrzebujesz metody, która może przyjąć blok, a następnie wykonać go raz lub więcej razy w tym samym kontekście co twoja metoda, to to robi. Gdybym musiał zgadywać, może chcesz przekazać argumenty także blokowi? Wiem, że to możliwe, ponieważ RSpec to robi, i to prawda, że ​​ten przykład nie. Powinienem rzucić okiem na kod RSpec i zobaczyć, jak to robią. –

+0

Rzeczywiście widzę, że RSpec nie przekazuje parametrów do blokowania, a do wywołania bloków używa klasy instance_eval. Zobacz http://rubydoc.info/gems/rspec-core/RSpec/Core/Example#run-instance_method i kliknij "Wyświetl źródło". –

3

To oczywiste:

class Object 
    def your_method(*args, &block) 
    instance_eval &block 
    end 
end 

receiver = Object.new 

receiver.your_method do 
    puts self #=> it will print the self of receiver 
end 
+0

Przepraszam, to, co chcę, to metoda, która przyjmuje blok i w tym bloku self jest zmieniany na odbiorcę, podobnie jak instance_eval! – gaols

+0

Jeszcze raz dziękuję za pomoc! – gaols

Powiązane problemy