Как получить объект контекста вызывающей стороны в Ruby? - PullRequest
3 голосов
/ 10 апреля 2010

здесь и далее - мой фрагмент кода, который я хочу упростить, чтобы избежать передачи дополнительного аргумента при каждом вызове. Фактически, мой сценарий использования состоит в том, что M - это пользовательская библиотека без определения аргумента context для каждого метода. check - это метод, который не определен пользователем.

# 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

Спасибо за вашу поддержку!

Ответы [ 2 ]

5 голосов
/ 24 июня 2010

Наткнулся на этот пост, когда искал ответ для своих собственных целей.

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

sudo gem install sender

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

http://rubygems.org/gems/sender

1 голос
/ 11 апреля 2010

Не то, что вы просите, но если бы 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

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

...