Acho profundamente estranho que isso seja possível em Ruby (não vou dizer imediatamente como):
obj = #code redacted
print obj.state # Some value.
LValue = obj
print obj.state # Different value!
Seu desafio é criar código aproximadamente neste formulário. Crie um objeto e atribua-o a uma variável. Ele deve ter algum atributo definido (ou método determinístico e idempotente) como state
acima, que muda após o objeto ser atribuído a um novo identificador ( LValue
acima), mesmo se você ainda usar o identificador antigo ( obj
acima) para fazer referência a ele.
Edite para enfatizar : state
ou o equivalente deve ser idempotente, portanto, criar um acessador que modifique o valor ou, por qualquer outro motivo, retorne resultados diferentes quando chamado várias vezes seguidas, não é uma solução válida. Ou, mais simplesmente, deve ser a atribuição que muda de estado.
Qualquer idioma com atribuição é elegível, embora haja provavelmente alguns em que não há solução totalmente legítima. Vou postar minha resposta em Ruby se ninguém mais receber depois de alguns dias e aceitar as respostas mais votadas em uma base contínua.
fonte
LValue = obj
É necessário que a linha sejastate
realmente alterada? (Eu poderia apenas fazer uma propriedade em C # que incrementos cada vez que você obtê-lo)(setq a (list "val")) (setq b (nconc a "val2"))
por exemplo.a
acaba avaliando("val" . "val2")
nesse momento.Respostas:
C ++
Isso é trivial usando as ferramentas certas.
Saída:
fonte
PHP (compilação de depuração,> = 5.4)
Usamos refcount do objeto em um getter. (Assim, pela atribuição, refcount aumenta e altera valores)
fonte
C #
Duas opções simples:
Ou podemos simplesmente escrever na mesma memória:
fonte
TeX, muito mais curto que as outras respostas aqui
Como sistema de composição tipográfica, o TeX possui um tipo de "caixa", que contém material tipográfico. Como o caso de uso mais comum é mover esse material, dividi-lo etc., em vez de fazer cópias dele, as caixas são normalmente excluídas quando usadas (ou melhor, as variáveis "caixa" são ponteiros e apenas um ponteiro por vez pode apontar para uma caixa real na memória). Não há necessidade de mágica.
fonte
C ++ 11 (Então vocês se esqueceram de unique_ptr / shared_ptr :-))
fonte
Fortran 03
Isso é um pouco semelhante à resposta D de Hugo, mas é um pouco mais oculto (em parte porque quem o # $% ^ conhece Fortran orientado a objetos)?
A saída é
Se você pode descobrir o que aconteceu, pontos de bônus para você! Se não:
fonte
PowerShell
Isso cria um objeto cuja
state
propriedade são os nomes das variáveis que apontam para o objeto.Saída
Nota: Isso não funciona se a atribuição ocorrer em um escopo filho.
Saídas
fonte
Perl 5
Aqui está uma maneira de fazer isso no Perl:
Isso gera:
Explicação:
Esta é uma aplicação direta de sobrecarga . Especificamente, sobrecarrego o operador de conversão de string
""
, que é chamado quando o objeto sobrecarregado é atribuídosubstr()
(que, sim, é um valor legal em Perl).Também existem muitas variáveis especiais no Perl que restringem qualquer coisa que lhes seja atribuída. Por exemplo, o seguinte também funciona:
Solução alternativa
Aqui está outra maneira de fazer isso:
Aqui
state
está um método (poderíamos torná-lo um atributo com mais travessuras de empate / sobrecarga, mas isso complicaria as coisas) que literalmente conta o número de referências ao objeto. Portanto, diferente da primeira solução, você realmente precisa atribuir$obj
a uma variável normal que pode conter uma referência de objeto para alterar o estado.fonte
Javascript
Ok, então eu fiz uma versão mais curta que funciona como SSCCE, mas não tenta mais analisar o JavaScript corretamente, portanto a contagem de referência pode não funcionar quando inserida em um script mais complexo.
fonte
Python
Está enganando um pouco, mas que tal:
fonte
C ++ 11
embora isso possa ser estendido para outros idiomas que suportam destruidores implícitos / explícitos
fonte
new
sem umdelete
no programa. Embora, para esta tarefa é bom o suficiente eu acho :)cout
linha para cima antes de}
e diga se isso funciona. :-)Scala
As conversões implícitas permitem fazer isso ao atribuir a uma variável local normal:
Você também pode fazer isso com tipos inferidos:
Você também pode usar um método setter personalizado, embora isso exija que o valor L seja um campo:
fonte
D
Saída:
fonte
Rubi
Como prometido, aqui está a resposta que inspirou a pergunta.
Class.new
cria uma classe anônima. Chamarto_s
uma classe anônima fornece a representação padrão de string dos objetos, com a qual se parece#<Class:0x007fe3b38ed958>
. No entanto, uma vez que a classe foi atribuída a uma constante, elato_s
se torna essa constante. No Ruby, uma constante é uma variável que começa com uma letra maiúscula, assimobj
como uma referência à classe que permite que ela permaneça anônima.Meu código envolve
to_s
umstate
método, então a saída se tornaDiferentemente da maioria das soluções aqui, isso funciona apenas uma vez: atribuir
obj
a outra constante não altera sua representação de string e também não atribui um novo valor aLValue
.fonte
Em Java
Eu pensei que isso era impossível em Java. Mas…
Classe principal:
Classe Cat:
Fui inspirado por @tbodt.
fonte
Cat.x = 2
impressãoCat.x
.Cat otherCat = tom
o estado não teria mudado nada. É difícil acreditar que isso atenda à letra ou ao espírito das regras.C ++
Esse comportamento é realmente especificado no padrão (e é por isso que foi preterido).
Saída
O processo que causa isso é o mesmo que a resposta de Abhijit, mas sem exigir
std::move
a mesma resposta de marinus, mas usando uma classe padrão em vez de defini-la eu mesmo.Edit: eu estou adicionando alguma explicação. Na saída, "algum endereço" será realmente um valor hexadecimal para o endereço do número inteiro alocado.
std::auto_ptr
libera o ponteiro de lojas quando atribuído a outroauto_ptr
e define seu ponteiro interno para 0. A chamadaget()
recupera o acesso ao ponteiro de lojas.fonte
get()
? Por que retornaria 0 no final?auto_ptr
está obsoleto.Python
fonte
Python 2.x
Não consegui encontrar uma maneira adequada de fazer isso sem definir uma aula extra.
fonte
Java
Todas as outras soluções usam a forma de sobrecarga do operador em seu idioma. Java não tem sobrecarga de operador, então eu pensei que estava preso. Mas eu vim com alguma coisa.
Aqui está a classe principal:
Existem algumas linhas suspeitas, mas elas não fariam nada se a
Thing
aula fosse completamente normal. Não é:Não é garantido que funcione por causa dos threads, mas eu testei no JDK 1.8u5 e funciona lá.
fonte
Lisp comum
Eu defino estado como o número de variáveis especiais vinculadas a um vetor. Portanto, a atribuição a uma variável especial altera o estado.
Saída:
Ele funciona apenas com atribuições a variáveis especiais, não a variáveis lexicais nem a slots dentro de um objeto.
Cuidado com a
do-all-symbols
aparência em todos os pacotes, para que ele perca as variáveis que não têm pacote. Pode contar dois símbolos que existem em mais de um pacote (quando um pacote importou o símbolo de outro pacote).Rubi
Ruby é quase o mesmo, mas eu defino estado como o número de constantes referentes a uma matriz.
Saída:
Esta é uma generalização da resposta do histocrata para objetos Ruby que não são classes ou módulos. O aviso aparece porque a constante Config carrega automaticamente algum código que o criou.
fonte
C ++
O resultado pode ser diferente em diferentes plataformas. Testado em ideone .
Saída:
fonte
C #
Saída:
fonte
=
?B
para umA
, porqueimplicit operator A(B b)
tem efeitos colaterais.