【问题标题】:Dynamic class creation, problem with function definition inside block: function body does not see local scope动态类创建,块内的函数定义问题:函数体看不到本地范围
【发布时间】:2011-11-14 11:30:12
【问题描述】:

我正在编写一个函数来动态创建类。我遇到了 *vars 变量(如下)的问题,在传递给 Class::new 的块内,“def initialize”方法看不到 *vars 的值(因此 Ruby 在 *vars 上报告未绑定变量错误)。

怎么办?

谢谢!

class MyParentClass
    def do_something_with(*args)
    end
    def do_something_else_with(*vars)
    end
end

def create_class(class_name,*vars)

    new_class = Class::new(MyParentClass) do
            def initialize(*args)
                super
                do_something_with(args)
                do_something_else_with(vars)
            end
        end
    Object::const_set(class_name.intern,new_class)
end 

    # Ruby: Error: *vars is unbound variable
    # My notes: *vars is in scope inside the do..end block passed to Class::new, but cannot be seen inside def initialize (why?) . And, how to fix this?

【问题讨论】:

  • 您可以使用类变量来破解它来存储数据,然后在初始化函数中检索它。但是,我正在寻找更清洁的解决方案(如果有的话?)我已经尝试过了,并且使用 class_var hack 可以正常工作。使用类变量是有意义的,因为如果我要自己手动继承 MyParentClass,在代码中通过键入,我将调用“do_something_else_with(vars)”,变量是我在代码中键入的静态字符串;我想手动将其输入源代码与将其动态存储在 class_var 中相同 - 它必须存储在某个地方!

标签: ruby class dynamic


【解决方案1】:

我不确定你想用这个装置达到什么目的,但经过一些改变后它可以工作(嗯,取决于你对“工作”的定义):

class MyParentClass
  def do_something_with(*args)
    puts "something #{args.inspect}"
  end
  def do_something_else_with(*vars)
    puts "else #{vars.inspect}"
  end
end

def create_class(class_name,*vars)

  new_class = Class::new(MyParentClass) do
    define_method :initialize do |*args|
      super()
      do_something_with(*args)
      do_something_else_with(*vars)
    end
  end
  Object::const_set(class_name.intern,new_class)
end

create_class :MyClass, 1, :foo, :bar
MyClass.new(2, :baz)

使vars 可见的技巧是使用闭包定义构造函数。

【讨论】:

  • 哇,谢谢!这很好用!我不知道define_method和def之间有区别......在这种情况下,您是否以某种方式覆盖了默认初始化(使用def initialize定义)?
  • 我正在尝试做的事情:动态解析一个文本文件,根据我解析的内容创建类。它与硬件工程而不是软件有关:)
猜你喜欢
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多