Ruby如何在语义上处理赋值?

时间:2015-04-20 19:19:21

标签: ruby variable-assignment assignment-operator

在Ruby中,我们使用=运算符为对象赋值。

将此与隐式输入相结合,我们经常遇到这样的情况:

myVar= :asymbol

上面的行都创建了一个新的符号对象,并将对象绑定到变​​量名myVar

从语义上讲,这是怎么做到的?

我已经在脑海中敲定了=运算符魔法语法内置于解释器中,但实际上只是object.=(value)方法的语法糖。

考虑到这一点,我最好的猜测是,当解释器看到我们试图为未定义的变量名称赋值时,它首先创建一个特殊类型的新对象,如undefined或{{ 1}}或者其他什么,然后将null消息传递给该对象,其中有效负载是我们尝试分配的值。

但是,在未实例化的对象上调用:=只会引发异常,因为Ruby认为我们正在尝试调用一个方法(其名称是您尝试生成的变量的名称) ).class

self

所以,据我所知,我无法通过实验来解决这个问题。


旁注:

在符号赋值的情况下,我相信分配的值(AKA实例化对象的> obj.class > NameError: undefined variable or method 'obj' for main:Object 方法返回的值,AKA是C级别上object_id变量的值)是表示某个表中某个偏移量的数字(我相信这就是Ruby为符号对象实现'立即值'的方式)。

在其他情况下,该值可能是对象本身的直接编码,或者是指在引用unsigned long VALUE时强制转换为指针的值。

无论如何,Ruby代表对象的方式以及我们最终是否分配引用或对象本身并不是我在这里要求的。

其他问题:

继承自struct方法的类是什么?我在ObjectBasicObject的规范中找不到它。

1 个答案:

答案 0 :(得分:13)

在技术意义上,变量只是指向对象的指针。没有什么值得注意的,但是对现有对象的简单变量赋值不涉及任何方法调用或消息被发送。

记住变量就在那里,以便程序员可以通过名称而不是某种内部标识符或内存位置来引用对象。所以这里有一些“魔法”,=在作出任务时很特别,因为你可以在左右两侧做什么规则。

如果你以编译器理解的方式定义消息,那么你可以将消息发送给某些东西,即make方法调用。 x = 1就足够了,这意味着x指的是有问题的Fixnum。

请注意,Ruby解释器需要确定x是否引用变量或方法调用,因为x=可能是在评估它的对象上下文中定义的方法。

例如:

class Example
  def x=(value)
    @x = value
  end

  def test
    # Equivalent to send(:x=, 1) because x= is a method
    x = 1

    # Is a variable definition because y= is not a method
    y = 2

    # Is always a method call because self is referenced.
    self.x = 3
  end
end

# Is a variable definition because x= is not defined in this context
x = 4

如果您的对象没有x=方法,则x会自动被假定为变量。

您不能拥有:=消息,因为这意味着您可以将一个对象替换为另一个对象,这是不允许的。创建对象后,它无法神奇地更改类型。为此,您需要创建另一个对象的新实例。变量似乎只会改变类型,但实际上,它们最终会指向不同的对象。

简而言之,没有:=方法调用,但可能有一些特殊的方法,如:x=,可以在非常具体的情况下使用。