Можно ли переопределить 0 в рубине?

На самом деле я не собираюсь использовать это ни в чем, если это действительно работает, но возможно ли переопределить 0, чтобы он действовал как 1 в Ruby, а 1 - как 0? Где на самом деле FixNum хранит свое значение?

2 ответа

Решение

Нет, я так не думаю. Я был бы очень удивлен, если бы тебе удалось. Если вы начнете переопределять методы / операторы Fixnum, вы можете приблизиться к этому (например, переопределить +, чтобы 1+5 => 5, 0+5 => 6 и т. Д.), Но вы не получите полную замену литерала '0' на значение 1. По крайней мере, маршаллинг для native показал бы действительное значение 0 Fixnum(0).

Если честно, я не совсем уверен, сможете ли вы переопределить основные операции, такие как + оп на Fixnum. Это может сломать так много вещей..

Насколько я помню из источника 1.8.3, простые целые и двойные числа хранятся прямо в "значении" и копируются вокруг *). Не существует единственного значения "0", "1" или "1000". Нет дополнительной разыменования, которая позволила бы вам поменять все значения одним выстрелом. Я сомневаюсь, что это изменилось в 1.9, и я сомневаюсь, что кто-то получил какое-то странное представление об этом в 2.0. Но я на самом деле не знаю. Тем не менее, это было бы странно. Нет платформы, которую я знаю, интерны целые и плавающие. Строки, иногда литералы массивов, но числа?

Так что, извините, нет #define true false шутки:)

-

*) разъяснение от Йорг W Mittag (спасибо, это именно то, что я имел в виду):

(..) Fixnums не имеют места в памяти, их значение указателя является "магическим" (в том смысле, что это не может произойти в Ruby-программе) и обрабатывается специально системой времени выполнения. Читайте о "представлении тегированного указателя", например, здесь.

Назначение не псевдоним объектов Fixnum. Фактически существует только один экземпляр объекта Fixnum для любого заданного целочисленного значения, поэтому, например, вы не можете добавить одноэлементный метод к Fixnum. Любая попытка добавить одноэлементный метод к объекту Fixnum вызовет TypeError. Источник

Это в значительной степени означает, что вы не можете редактировать Fixnum и, следовательно, не переопределять 0 или же 1 в родном рубине.

Хотя эти Fixnum также являются объектами, они имеют уникальные идентификаторы объектов, которые четко ссылаются на них где-то в памяти. См. BasicObject#__id__

Если вы можете найти место в памяти, где 0 а также 1 объекты и переключать их, вы должны иметь эффективную коммутацию 0 а также 1 Поведение в ruby, как и сейчас, будет ссылаться на другой объект.

Итак, чтобы ответить на ваш вопрос: никакое переопределение Fixnums невозможно в Ruby, хотя переключение их поведения должно быть возможным.

Другие вопросы по тегам