Подтвердить что ты не робот

Как Ruby обрабатывает назначение семантически?

В Ruby мы присваиваем значения объектам с помощью оператора =.

Объедините это с неявной типизацией, и мы часто получаем такие ситуации:

myVar= :asymbol

Вышеприведенная строка создает новый объект символа и связывает объект с именем переменной myVar.

Семантически, как это делается?

Я забил в голову, что оператор = - это не магический синтаксис, встроенный в интерпретатор, но на самом деле просто синтаксический сахар для метода object.=(value).

Учитывая это, я думаю, что когда интерпретатор видит, что мы пытаемся присвоить значение имени переменной undefined, он сначала создает новый объект некоторого специального типа, например undefined или null или что-то, а затем передает сообщение := этому объекту с полезной нагрузкой, являющейся значением, которое мы пытаемся назначить.

Однако вызов .class для объекта, не созданного экземпляром, просто генерирует исключение, поскольку Ruby думает, что мы пытаемся вызвать метод (чье имя является именем переменной, которую вы пытаетесь создать) self

> obj.class
    > NameError: undefined variable or method 'obj' for main:Object

Итак, насколько я могу судить, я не могу понять это экспериментально.


Боковое примечание:

В случае назначения символа я считаю, что присвоенное значение (AKA - значение, возвращаемое методом созданного объекта object_id, AKA - значение переменной unsigned long VALUE на уровне C) - это число, которое представляет собой смещение в таблице где-нибудь (я считаю, что именно так Ruby достигает "немедленного значения" для объектов символа).

В других случаях это значение может быть прямым кодированием самого объекта или значением, которое предназначено для указания указателю в отношении struct.

Независимо от того, каким образом Ruby представляет объект, и в конечном итоге мы назначаем ссылку или сам объект, это не то, о чем я прошу здесь.

Дополнительный вопрос:

Каким классом является метод =, унаследованный от? Я не могу найти его в спецификации для Object или BasicObject.

4b9b3361

Ответ 1

Переменные, в техническом смысле, просто указывают на объекты. В этом нет ничего примечательного, но простое присвоение переменной существующему объекту не связано с вызовами методов или отправляемыми сообщениями.

Помните, что переменные существуют только там, чтобы программисты могли ссылаться на объекты по имени, а не на какой-то внутренний идентификатор или местоположение памяти. Итак, здесь есть немного "магии", = является особенным при создании задания, так как есть правила для того, что вы можете делать с левой и с правой стороны.

Единственный способ отправить сообщения на что-то, то есть делать вызовы методов, - это определить его таким образом, каким понимает компилятор. 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=, которые работают в очень специфических случаях.