是否有任何方法可以在所调用的块内握住调用对象。例如,是否有任何方法可以访问该方法的范围 batman 或班级 SuperHeros

class SuperHeros

  attr_accessor :news

  def initialize
    @news = []
  end

  def batman task
    puts "Batman: #{task} - done"
    yield "feed cat"
    @news << task
  end

end

cat_woman = lambda do |task| 
  puts "Cat Woman: #{task} - done" 
  # invoker.news << task
end

robin = lambda do |task| 
  puts "Robin: #{task} - done"
  # invoker.news << task
end


characters = SuperHeros.new
characters.batman("kick Joker's ass", &cat_woman)
characters.batman("break Bane's bones", &robin)
有帮助吗?

解决方案

您可以使用类似的东西 实例评估与委托 模式,使用 - 例如 - 在 Savon 宝石:

def batman(task, &block)
  @original_self = eval('self', block.binding)
  puts "Batman: #{task} - done"
  instance_exec('feed cat', &block)
  @news << task
end

private

def method_missing(method, *args, &block)
  if @original_self
    @original_self.send(method, *args, &block)
  else
    super
  end
end

在这种方法中,当您调用方法(带有隐式接收器)内部块中的方法传递到 batman 方法,在 SuperHeros 实例。如果没有此类方法,请进行呼叫(通过 method_missing)到原始块 self.

其他提示

将接收器对象在一个块内的最简单方法是将对象分配给实例变量。

此示例更清楚地说明了Lambdas Cat_woman和Robin如何访问块的接收器对象的属性:

class SuperHeros
  attr_accessor :news, :name, :current_task

  def initialize(a_name)
    @name = a_name
    @news = []
  end

  def batman(task)
    puts "Inside the method batman of #{name}: #{task} in progress ..."
    @current_task = task
    yield
    @news << task
  end

end

cat_woman = lambda do |extra_task|
  puts "cat_woman even #{extra_task} before doing #{@caller_obj.current_task}"
  puts "Cat Woman: #{@caller_obj.current_task} - done by #{@caller_obj.name}"
  # invoker.news << task
end

robin = lambda do |extra_task|
  puts "robin even #{extra_task} before doing #{@caller_obj.current_task}"
  puts "Robin: #{@caller_obj.current_task} - done by #{@caller_obj.name}"
end


character_1 = SuperHeros.new('batman_1')
(@caller_obj = character_1).batman("kick Joker's ass") { cat_woman['eats some burger'] }

puts

character_2 = SuperHeros.new('batman_2')
(@caller_obj = character_2).batman("break Bane's bones") { robin['drinks some beer'] }

输出将是:

Inside the method batman of batman_1: kick Joker's ass in progress ...
cat_woman even eats some burger before doing kick Joker's ass
Cat Woman: kick Joker's ass - done by batman_1

Inside the method batman of batman_2: break Bane's bones in progress ...
robin even drinks some beer before doing break Bane's bones
Robin: break Bane's bones - done by batman_2
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top