2010-04-10 3 views
3

в дальнейшем - это моя часть кода, которую я хочу упростить, чтобы избежать передачи дополнительного аргумента для каждого вызова. На самом деле, мой usecase заключается в том, что M является пользовательской библиотекой без определения аргумента context для каждого метода. check - это метод, который не определен пользователем.Как получить объект контекстного вызова в Ruby?

# User code 
module M 
    def do_something(context) 
    puts "Called from #{context}" 
    context.check 
    end 
    module_function :do_something 
end 

# Application code 
class Bar 
    def check 
    puts "Checking from #{self}..." 
    end 
end 

class Foo < Bar 
    def do_stuff(scope, method) 
    scope.send method, self 
    end 
end 

# Executed by user 
Foo.new.do_stuff M, :do_something 

Есть ли способ сделать то же думать, не проходя self в качестве входного аргумента do_something метод для того, чтобы восстановить check метод?

# User code 
module M 
    def do_something 
    called_from_object = ??? 
    puts "Called from #{called_from_object}" 
    called_from_object.check 
    end 
    module_function :do_something 
end 

# Application code 
class Bar 
    def check 
    puts "Checking from #{self}..." 
    end 
end 

class Foo < Bar 
    def do_stuff(scope, method) 
    scope.send methood 
    end 
end 

# Executed by user 
Foo.new.do_stuff M, :do_something 

Благодарим за поддержку!

ответ

1

Не то, о чем вы просите, но если бы Foo включили M, это позволило бы вам достичь того, что вам нужно? например

module M 
    def do_something 
    puts "I am going to use the test method from the including class" 
    test 
    end 
end 

class Foo 
    include M 
    def test 
    puts "In Foo's test method" 
    end 

    def do_stuff 
    do_something 
    end 
end 

, а затем вы можете сделать:

irb(main):019:0> Foo.new.do_stuff 
I am going to use the test method from the including class 
In Foo's test method 

Если идея состоит в том, чтобы иметь модуль обеспечивают некоторую общую функциональность и имеют специфику в классе, то это довольно распространенный вид в рубин, например, модуль Comparable, требующий применения класса включения <=>.

+0

Я посмотрел на Сравнительном модуле, но я не вижу связи между моим вопросом и этим модулем ... Вы можете пойти более в деталь? – David

+0

Когда модуль был исправлен как конкретный модуль (например, 'M' в исходной версии вопроса), тогда класс' Foo' мог просто включать 'M', а затем, когда' do_stuff' вызывал включенное 'do_something' self, было бы экземпляр Foo. Однако, если модуль передается как параметр do do_stuff (как в обновленном примере), то я думаю, вам понадобится другой подход. – mikej

+0

Благодарим за эту обратную связь. Я согласен в случае с конкретным модулем 'M'. Мой первоначальный пост был конкретным случаем, который не отражал то, что я действительно хочу сделать. – David

5

Нашел этот пост, ища ответа для моих собственных целей.

Не нашел подходящего, поэтому я вырыл источник Ruby и соединил расширение. Я в комплекте его как следует установить GEM-без каких-либо проблем до тех пор, как вы используете рубин 1.9.1:

Судо камень установить отправителю

Это не будет работать с Ruby 1.8 , так как 1.8 имеет другую модель для отслеживания кадров.

http://rubygems.org/gems/sender

Смежные вопросы