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

Luk*_*uke 13 ruby variable-assignment assignment-operator

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

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

myVar= :asymbol
Run Code Online (Sandbox Code Playgroud)

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

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

我已经在脑子里敲了一下,=操作符不是内置在解释器中的魔法语法,但实际上只是该object.=(value)方法的语法糖.

考虑到这一点,我最好的猜测是,该解释认为我们正在试图将值赋给一个未定义的变量名的时候,它首先会创建一些特殊类型的新对象,像undefinednull什么的,然后传递:=消息到有效载荷的对象是我们试图分配的值.

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

> obj.class
    > NameError: undefined variable or method 'obj' for main:Object
Run Code Online (Sandbox Code Playgroud)

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


边注:

在符号赋值的情况下,我相信分配的值(AKA实例化对象的object_id方法返回的值,AKA unsigned long VALUE在C级别上的变量的值)是一个数字,表示某个表中的偏移量(我相信这个Ruby是如何实现符号对象的"直接价值"的.

在其他情况下,该值可以是对象本身的直接编码,或者意图在参考a时强制转换为指针的值struct.

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

附加问题:

=继承自哪个类的方法?我在ObjectBasicObject的规范中找不到它.

tad*_*man 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
Run Code Online (Sandbox Code Playgroud)

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

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

简而言之,没有:=方法调用,但可能有特殊的方法:x=在非常特殊的情况下工作.

  • @CarySwoveland一切都好.但是,程序员与自己交谈以解决问题并不罕见! (2认同)