【问题标题】:How Do I Make This Code Set the Value of the Instance Variable?如何使此代码设置实例变量的值?
【发布时间】:2012-05-14 13:23:04
【问题描述】:

我有以下代码,旨在将普通变量转换为实例变量。

BasicObject.class_eval do
    def instance(ins)
        self.instance_variable_set("@#{ins}", ins)
    end
end

假设用户说

class X
  foo = 3
end
bar = X.new
bar.instance(:foo)

我想要它做的是将新创建的变量 @foo 设置为 3,而不是将 @foo 设置为 :foo。如何让代码做我想做的事?

【问题讨论】:

  • 代码示例定义了一个 foo,它只在 class ... end 块中可见。即使你回到 X 类,它也消失了——它是词汇范围的一部分,而不是类。这些“正常”变量在创建它们的范围之外永远不可见。一旦你点击了关闭它们的块的end,它们就只能被该块中定义的代码访问。而且上面没有任何这样的代码。您要解决的实际问题是什么?
  • 你到底为什么想要这个复杂的代码?你的目标是什么?

标签: ruby class dynamic methods instance-variables


【解决方案1】:

在您的instance 方法中,参数ins 包含变量的名称,而不是其值。正如所写的那样,从那时起没有办法获得它的价值。

如果您从代码中源变量实际可见的点调用instance,但在您的示例中不存在(请参阅我上面的评论),您也可以传递局部变量绑定,然后使用它。像这样的:

def instance(var, bound)
    eval "@#{var}=#{var}", bound
end

这会像这样工作:

foo = 3
instance('foo', binding)
@foo   # => 3

【讨论】:

  • 我很困惑,绑定是什么意思?
  • 一个Binding对象,代表代码中某一点可见的变量集。当前绑定是由binding方法返回的,所以上面的代码是字面量的; binding 已预先声明,您无需执行任何操作即可使其正常工作。您可以获取结果并将其作为第二个参数传递给 eval,这使得同一组变量对 evaled 代码可见 - 这几乎是您对 Binding 对象所能做的所有事情。
猜你喜欢
  • 2020-02-05
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 2017-04-16
  • 2019-02-01
  • 2010-11-07
  • 1970-01-01
相关资源
最近更新 更多