Я нахожу глубоко странным, что это возможно в Ruby (я не буду сразу говорить, как):
obj = #code redacted
print obj.state # Some value.
LValue = obj
print obj.state # Different value!
Ваша задача - создать код примерно такой формы. Создайте объект и назначьте его переменной. Он должен иметь некоторый определенный атрибут (или детерминированный, идемпотентный метод), как state
указано выше, который изменяется после того, как объекту присвоен новый идентификатор (см. LValue
Выше), даже если вы все еще используете старый идентификатор (см. obj
Выше) для ссылки на него.
Отредактируйте для выделения : state
или эквивалент должен быть идемпотентным, поэтому создание метода доступа, который изменяет значение или по любой другой причине возвращает разные результаты при вызове несколько раз подряд, не является допустимым решением. Или, проще говоря, это должно быть присвоение, которое изменяет состояние.
Любой язык с заданием является приемлемым, хотя, вероятно, есть такие, где нет полностью законного решения. Я опубликую свой ответ Ruby, если никто не получит его через несколько дней, и буду принимать ответы с наибольшим количеством голосов по мере поступления.
источник
LValue = obj
линия быть обязательной дляstate
фактического изменения? (Я мог бы просто сделать свойство в C #, которое увеличивается каждый раз, когда вы его получаете)(setq a (list "val")) (setq b (nconc a "val2"))
например.a
в конечном итоге оценки, как("val" . "val2")
на тот момент.Ответы:
C ++
Это тривиально, используя правильные инструменты.
Выход:
источник
PHP (отладочная сборка,> = 5.4)
Мы используем refcount объекта в геттере. (Таким образом, по присваиванию refcount увеличивается и значение изменяется)
источник
C #
Два простых варианта:
Или мы могли бы просто написать в ту же память:
источник
TeX, намного короче других ответов здесь
Как система набора текста, TeX имеет тип «box», который содержит материал набора. Поскольку наиболее распространенный вариант использования - это перемещать этот материал, разбивать его и т. Д., А не копировать его, ящики обычно удаляются при использовании (или, скорее, переменные «ящика» являются указателями, и только один указатель за раз может указывать фактической коробке в памяти). Не нужно никакой магии.
источник
C ++ 11 (так что вы, ребята, забыли об unique_ptr / shared_ptr :-))
источник
Фортран 03
Это несколько похоже на D-ответ Хьюго, но немного более скрыто (отчасти потому, что кто знает, что $ $ ^ знает объектно-ориентированный фортран)?
Выход
Если вы можете выяснить, что произошло, бонусные очки вам! Если не:
источник
PowerShell
Это создает объект, чьим
state
свойством являются имена переменных, которые указывают на объект.Выход
Примечание. Это не работает, если назначение происходит в дочерней области.
Выходы
источник
Perl 5
Вот один из способов сделать это в Perl:
Это выводит:
Объяснение:
Это прямое применение перегрузки . В частности, я перегружаю оператор преобразования строк
""
, который вызывается, когда назначается перегруженный объектsubstr()
(который, да, является допустимым значением l в Perl).В Perl также есть множество специальных переменных, которые преобразуют все, что им назначено. Например, следующее также работает:
Альтернативное решение
Вот еще один способ сделать это:
Вот
state
метод (мы могли бы сделать его атрибутом с дальнейшими махинациями связывания / перегрузки, но это усложнило бы ситуацию), который буквально подсчитывает количество ссылок на объект. Таким образом, в отличие от первого решения, вам фактически нужно назначить$obj
обычную переменную, которая может содержать ссылку на объект, чтобы изменить состояние.источник
JavaScript
Итак, я сделал более короткую версию, которая работает как SSCCE, но больше не пытается правильно анализировать JavaScript, поэтому подсчет ссылок может не работать, если поместить его в более сложный скрипт.
источник
питон
Это немного обманывает, но как насчет:
источник
C ++ 11
хотя это может быть расширено для других языков, которые поддерживают неявные / явные деструкторы
источник
new
без единогоdelete
в программе. Хотя, для этой задачи это достаточно хорошо, я думаю :)cout
строку вверх перед}
и скажите, работает ли это. :-)Scala
Неявные преобразования позволяют вам сделать это при назначении нормальной локальной переменной:
Вы также можете сделать это с помощью выводимых типов:
Вы также можете использовать пользовательский метод установки, хотя для этого требуется, чтобы L-значение было полем:
источник
D
Выход:
источник
Рубин
Как и было обещано, вот ответ, который вдохновил вопрос.
Class.new
создает анонимный класс. Вызовto_s
анонимного класса дает строковое представление объектов по умолчанию, которое выглядит следующим образом#<Class:0x007fe3b38ed958>
. Однако, как только класс был присвоен константе, онаto_s
становится этой константой. В Ruby константа - это переменная, которая начинается с заглавной буквы, поэтомуobj
а также ссылка на класс, который позволяет ей оставаться анонимным.Мой код оборачивается
to_s
вstate
метод, поэтому вывод становитсяВ отличие от большинства решений здесь, это работает только один раз: присвоение
obj
другой константе не изменит ее строковое представление, и ни один не присвоит новое значениеLValue
.источник
На яве
Я думал, что это невозможно в Java. Но…
Основной класс:
Класс Cat:
Я был вдохновлен @tbodt.
источник
Cat.x = 2
печатиCat.x
.Cat otherCat = tom
состояние бы совсем не изменилось. Мне трудно поверить, что это соответствует букве или духу правил.C ++
Такое поведение на самом деле указано в стандарте (и именно поэтому оно устарело).
Выход
Процесс, который вызывает это, совпадает с ответом Абхиджита, но не требует
std::move
и такой же, как ответ маринуса, но использует стандартный класс вместо того, чтобы определять его сам.Изменить: я добавляю некоторые объяснения. В выводе «некоторый адрес» фактически будет шестнадцатеричным значением для адреса выделенного целого числа.
std::auto_ptr
освобождает свой указатель хранилищ при назначении другомуauto_ptr
и устанавливает свой внутренний указатель равным 0. Вызовget()
возвращает доступ к указателю хранилищ.источник
get()
? Зачем возвращать 0 в конце?auto_ptr
устарела.питон
источник
Python 2.x
Я не мог найти правильный способ сделать это без определения дополнительного класса.
источник
Джава
Все остальные решения используют перегрузку операторов в своем языке. В Java нет перегрузки операторов, поэтому я подумал, что застрял. Но я что-то придумал.
Вот основной класс:
Есть несколько подозрительных строк, но они ничего не сделают, если
Thing
класс будет полностью нормальным. Это неОн не гарантированно работает из-за потоков, но я протестировал его на JDK 1.8u5, и он работает там.
источник
Обыкновенный Лисп
Я определяю состояние как число специальных переменных, связанных с вектором. Итак, присвоение специальной переменной меняет состояние.
Выход:
Он работает только с присваиваниями специальным переменным, а не лексическим переменным или слотам внутри объекта.
Остерегайтесь этого
do-all-symbols
выглядит во всех пакетах, поэтому он пропускает переменные, которые не имеют пакета. Это может привести к двойному счету символов, которые существуют в более чем одном пакете (когда один пакет импортировал символ из другого пакета).Рубин
Ruby почти такой же, но я определяю состояние как число констант, ссылающихся на массив.
Выход:
Это обобщение ответа гистократа на объекты Ruby, которые не являются классами или модулями. Предупреждение появляется, потому что константа Config автоматически загружает некоторый код, который сделал предупреждение.
источник
C ++
Результат может отличаться на разных платформах. Проверено на идеоне .
Выход:
источник
C #
Выход:
источник
=
?B
к aA
, потому что уimplicit operator A(B b)
него есть побочные эффекты.