Solicitação OpenStruct Pull [WIP]

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. O OpenStructcomportamento deve ser misturado a outras classes como um Módulo. No entanto, ainda existem casos de uso de apenas desejar um OpenStructobjeto simples .
  • OpenStructse comporta de forma semelhante a a Hash.OpenStructpode ser criado, atualizado e despejado a Hash. Ele ainda tem um método semelhante ao Hash#delete(), o OpenStruct#delete_field()método. No entanto, OpenStructfaltam alguns métodos-chave como mergeou merge!. Esses métodos funcionariam exatamente como o (já definido) OpenStruct#marshal_load(). Eu acredito que OpenStructse beneficiaria de apelidos que o fazem se comportar como Hashe respeitar o Princípio da Menor Surpresa .
  • Todos os métodos do OpenStructestã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 de OpenStruct#object_idno OpenStruct#inspectmé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 OpenStructobjeto e então o redefine e funciona. O congelamento deve parar de mudar o objeto, de qualquer forma.OpenStruct#frozen?
  • Também fiz uma série de melhorias importantes:
    • Para cumprir os requisitos do primeiro problema que tenho OpenStruct, criei um módulo aninhado na OpenStructclasse chamada M. 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/3460906Object#__send__OpenStruct#inspectOpenStruct#__inspect__OpenStruct#__freeze__OpenStruct#freezeOpenStruct#object_idOpenStruct#__object_id__
    • Eu adicionei a capacidade de apenas despejar um conjunto específico de chaves com o método.OpenStruct#__dump__
  • 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#bmbme 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