为什么我在此代码中遇到SystemStackError?

时间:2012-06-04 18:33:40

标签: ruby string class ruby-1.9

class X
  class << self
    def attr_string arg
      eval("def #{arg}; return #{arg.to_s}; end")
    end
  end
end

我正在使用的代码。我想把它变成一个类宏,比如attr_accessor。当我打电话

foo = 50
X.attr_string :foo
X.foo

我得到SystemStackError。这是为什么?

2 个答案:

答案 0 :(得分:0)

class X
  def attr_string arg
    (class << self; self; end).class_eval do
      define_method arg do
        arg
      end
    end
  end
end

或者小清洁

class X
  def self.attr_string arg
    self.class.instance_eval do
      define_method(arg) { arg.to_s }
    end
  end
end

答案 1 :(得分:0)

无限递归会做到。

选项1(使用类变量):

@@foo = 50

class X
  def X.attr_string arg
    eval("def X.#{arg.to_s}; return @@#{arg.to_s}; end")
  end
end
X.attr_string :foo
X.foo

选项2(在定义方法时指定值):

class X
  def X.attr_string arg, val
    eval("def X.#{arg.to_s}; #{val}; end")
  end
end
X.attr_string :foo, 50
X.foo

我猜return foo试图再次无限地运行foo方法。但即使您将变量命名为foo1并返回foo1,它也不会将foo1视为类变量,因为它已经丢失了范围。

您可以尝试将值包装在lambda中或封送foo对象。如果您对此感到满意,请将结果发布给所有人。

有趣的问题!