2014-09-24 2 views
1

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

+1

Я уверен, что числовые литералы обрабатываются парсером, так как вы не можете «def 0». –

ответ

1

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

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

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

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

-

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

(..) У Fixnums нет места в памяти, их значение указателя является «волшебным» (тем, что оно не может быть реализовано в программе Ruby) и обработано специально системой времени выполнения. Прочитайте «помеченное представление указателя», e.g. here.

0

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

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

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

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

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

+1

На самом деле, в MRI, YARV, Rubinius, MRuby, MacRuby и, возможно, в других, 'Fixnum' не имеют места в памяти, их значение указателя является «магическим» (тем, что оно не может быть реализовано в программе Ruby) и обрабатывается специально для системы времени выполнения. Прочитайте «помеченное представление указателя», например.[Здесь] (http://stackoverflow.com/a/25744887/2988). –

+0

@ JörgWMittag: Спасибо, это гораздо лучшее описание механизма, чем «прямо внутри« значения ». Я придумал. Я позволил себе включить ваш комментарий в текст, надеюсь, что вы не против. – quetzalcoatl

Смежные вопросы