Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何将方法传递给实例_eval?_Ruby_Metaprogramming_Instance Eval - Fatal编程技术网

Ruby 如何将方法传递给实例_eval?

Ruby 如何将方法传递给实例_eval?,ruby,metaprogramming,instance-eval,Ruby,Metaprogramming,Instance Eval,我想在此类上调用instance\u eval: class A attr_reader :att end 传递此方法b: class B def b(*args) att end end 但这种情况正在发生: a = A.new bb = B.new a.instance_eval(&bb.method(:b)) # NameError: undefined local variable or method `att' for #<B:0x007fb39a

我想在此类上调用
instance\u eval

class A
  attr_reader :att
end
传递此方法
b

class B
  def b(*args)
    att
  end
end
但这种情况正在发生:

a = A.new
bb = B.new
a.instance_eval(&bb.method(:b)) # NameError: undefined local variable or method `att' for #<B:0x007fb39ad0d568>
a=a.new
bb=B.新
a、 实例_eval(&bb.method(:b))#name错误:未定义的局部变量或方法“att”#

b
是一个块时,它可以工作,但是
b
作为一个方法不起作用。我怎样才能使它起作用?

你的目标究竟是什么还不清楚。通过在模块中定义类并在每个类中包含模块,可以轻松地在类之间共享方法

module ABCommon
  def a
    'a'
  end
end

class A
  include ABCommon
end

Anything = Hash
class B < Anything
  include ABCommon

  def b(*args)
    a
  end

  def run
    puts b
  end
end
模块ABCommon
定义a
“a”
结束
结束
甲级
包括ABCommon
结束
任何东西=散列
B类<任何
包括ABCommon
def b(*args)
A.
结束
def运行
放b
结束
结束

此答案没有使用所要求的实际方法,但我不需要返回
Proc
或更改
a
。这是一个DSL,
def_b
应该在域中有一个有意义的名称,如
configure
,并且它更可能在模块或基类中定义

class B
  class << self
    def def_b(&block)
      (@b_blocks ||= []) << block
    end

    def run
      return if @b_blocks.nil?
      a = A.new
      @b_blocks.each { |block| a.instance_eval(&block) }
    end
  end

  def_b do
    a
  end
end
B类

类,我希望在该类中有状态。
class B
  class << self
    def def_b(&block)
      raise "b defined twice!" unless @b_block.nil?
      @b_block = block
    end

    def run
      A.new.instance_eval(&@b_block) unless @b_block.nil?
    end
  end

  def_b do
    a
  end
end