Olá Ruby Core,
Nesta solicitação pull, fiz uma série de alterações que gostaria de adicionar ao ostruct da biblioteca stdlib do Ruby.
Antes de entrar em qualquer coisa, quero enfatizar uma coisa: todas as mudanças são geralmente compatíveis com as versões anteriores da biblioteca de ostruct . Quaisquer alterações não compatíveis são o que considero correções de bugs.
Primeiro, uma lista de problemas com a classe OpenStruct atual:
OpenStruct
é uma classe, mas muitas vezes só é usada para dar o comportamento flexível às aulas de crianças. OOpenStruct
comportamento deve ser misturado a outras classes como um Módulo. No entanto, ainda existem casos de uso de apenas desejar umOpenStruct
objeto simples .OpenStruct
se comporta de forma semelhante a aHash
.OpenStruct
pode ser criado, atualizado e despejado aHash
. Ele ainda tem um método semelhante aoHash#delete()
, oOpenStruct#delete_field()
método. No entanto,OpenStruct
faltam alguns métodos-chave comomerge
oumerge!
. Esses métodos funcionariam exatamente como o (já definido)OpenStruct#marshal_load()
. Eu acredito queOpenStruct
se beneficiaria de apelidos que o fazem se comportar comoHash
e respeitar o Princípio da Menor Surpresa .- Todos os métodos do
OpenStruct
estão abertos para fácil substituição. Além disso, alguns dos métodos usam outros métodos que provavelmente serão substituídos, como a chamada deOpenStruct#object_id
noOpenStruct#inspect
método. Também causa problemas como este: https://gist.github.com/3460906
Comecei a trabalhar em uma alternativa ao OpenStruct depois de ter alguns problemas com ele.
Em vez de modificar o OpenStruct, foi simplesmente mais fácil construir minha própria versão.
Depois de um tempo, abandonei-o até recentemente, quando precisei do OpenStruct novamente.
Decidi terminar meu trabalho atualizado com o que aprendi desde que comecei.
Fiz algumas coisas nesta solicitação pull:
- Corrigi pelo menos 3 bugs:
- Usar o método não removeria realmente o método fornecido, apenas a chave / valor da tabela. Isso cria uma incompatibilidade confusa no objeto e na tabela.
OpenStruct#delete_field
- Ao usá- lo, criaria métodos getter e setter para cada chave / valor. No entanto, também excluiria a tabela inteira.
OpenStruct#marshal_load
- Um dos testes congela um
OpenStruct
objeto e então o redefine e funciona. O congelamento deve parar de mudar o objeto, de qualquer forma.OpenStruct#frozen?
- Usar o método não removeria realmente o método fornecido, apenas a chave / valor da tabela. Isso cria uma incompatibilidade confusa no objeto e na tabela.
- Também fiz uma série de melhorias importantes:
- Para cumprir os requisitos do primeiro problema que tenho
OpenStruct
, criei um módulo aninhado naOpenStruct
classe chamadaM
. Esse módulo contém todo o comportamento e pode ser incluído quando necessário. - Projetei que todos os métodos públicos sejam agrupados em sublinhados duplos da mesma maneira que muitos outros métodos importantes são nomeados. Além disso, criei um alias para muitos métodos em suas formas de “sublinhado” (com ex- alias para ) para evitar confusão. Finalmente eu alias métodos “sublinhado” para os métodos importantes, como a . Por causa da natureza do método de alias , agora você pode definir uma chave / valor “ id de objeto ” e ainda ter acesso ao original com . Isso evita o bug listado na essência: https://gist.github.com/3460906
Object#__send__
OpenStruct#inspect
OpenStruct#__inspect__
OpenStruct#__freeze__
OpenStruct#freeze
OpenStruct#object_id
OpenStruct#__object_id__
- Eu adicionei a capacidade de apenas despejar um conjunto específico de chaves com o método.
OpenStruct#__dump__
- Para cumprir os requisitos do primeiro problema que tenho
- Finalmente, melhorei os testes desta biblioteca dividindo-os em partes gerenciáveis ou refinando-os para uma leitura melhor. Agora há teste para outros recursos
OpenStruct
, bem como testes para os novos recursos adicionados a esta solicitação de pull.
Finalmente, com essas coisas listadas, só tenho os benchmarks para mostrar.
Usei dois tipos de benchmarking, ambos Benchmark#bmbm
e gem’s de benchmark-ips Benchmark#ips
.
Ambos mostram resultados favoráveis para minha versão do ostruct.
Você notará que minha versão está rotulada AltStruct
, porque também é uma joia.
Aqui estão os links para os resultados: https://gist.github.com/3462357