A Ruby não faz distinção de elementos de um Array, o que eu acho uma vantagem fundamental, pois, a classe Array é uma classe para atender o escopo dos objetos remanescentes da linguagem. Como já conhecido por programadores em java, um array é de tamanho fixo e obedece a premissa que todos os elementos terão o mesmo tipo(considerando hierarquia). Em um aprendizado básico e inicial de uma linguagem de programação, a tipagem obrigatória é de fácil entendimento mas a coisa que contem coisas pode ou não aceitar tipos genéricos. Exemplo de uma mochila genérica no preposto abaixo
“Uma mochila onde aceita objetos menores que ela como, caneta, pendrive, laptop, absorvente, cueca, etc.”
Em uma tentativa de identificar o sexo do(a) dono(a) da mochila pelo seu conteúdo fica complicado pelo fato que ‘absorvente’ é usado por mulheres e ‘cueca’ por homens( normalmente é assim :).
Uma mochila genérica de um homem(deixa de ser genérica e passa a ser mochila-homem) não aceita ‘absorvente’ mas continua aceitando o catálogo de objetos masculinos. E outra coisa quando eu digo que a mochila ‘aceita objetos menores que ela’ também deixa de ser genérica e passa a ser limitada.
Limite por Tipo ou Aspecto
Em Java(a linguagem) as coleções tais como Vector e HashSet que antes da versão 1.5 recebiam apenas o tipo do topo da hierarquia ficando a critério do programador especificar em implementação de interfaces as conversões e verificação de tipo. Em uma proposta mais humana e menos burocrática o java 1.5 recebeu as definições de Generics tendo apenas a deficiência da dispersão das psedos-tags na declaração e na instância do objeto.
Array em Ruby o tipo não importa e também a linguagem não define uma limitação fixa da quantidade de elementos e as peculiaridades relativa a cada instância da coleção.
Considerando a linguagem na sua mais simples forma, a forma padrão sem APIs externas nenhuma das duas linguagens define uma coleção por aspecto.
Como seria este aspecto então?
Seria uma coleção capaz de determinar um contrato não burocrático sobre quais aspectos gostarias que a classe tenha. Algo como
“Aceite qualquer instância que siga a seguinte regra: tenha o método ’somar’ , criada na terça-feira, tenha a variável ‘hello’(string) com o conteúdo maior que 5″
Você deve estar pensando “Você tá ficando doido!!”… não, não é isso; isso é : Reduzir as condicionais para uso de elementos da coleção pense em “Coleções cuja as condicionais fiquem na entrada do elemento e não na saída”
De volta a pragmática…
Proponho aqui uma forma de criar um Array em Ruby que aceita apenas um tipo de classe, podemos estudar depois como fariamos algo utilizando os aspectos do objeto….
Módulo OnlyClass
Criei o módulo OnlyClass para facilitar o acoplamento na classe Array. Temos então a instância de um Array que aceita apenas um tipo de classe:
colecao=Array.only String
O uso da classe é normal, há apenas verificação de inclusão dos elementos, neste caso String.
colecao=Array.only String
colecao << "Um elemento"
colecao[1]="Dois elemento"
colecao.push("Mais um elemento","Mais n elementos")
Veja que o array adiciona os elementos sem problema. Mas quando um elemento não for do tipo especificado uma exceção será lançada.
colecao=Array.only String
colecao << "esse vai"
colecao << 333
Módulo OnlyClass obtendo elementos e elementos dos métodos
Criei uma forma automática de obter os elementos de um método específico que já é comum a todas as instâncias pertencentes a coleção. Um exemplo seria obter os sucessores de todos elementos de um Array#Fixnum, chamando o each_nome-do-método-de-instância e um bloco(opcional)
colecao=Array.only Fixnum
colecao << 10
colecao << 20
colecao.push(30,40)
colecao.each_succ {|n| puts n}
sem o bloco, atribuição do resultado em uma variável
colecao=Array.only Fixnum
colecao << 10
colecao << 20
colecao.push(30,40)
succs=colecao.each_succ
Podemos também passar parâmetros para o método, exemplo: obter todos os valores do resultado do match de cada elemento em um array.
colecao=Array.only String
colecao << "Um elemento"
colecao[1]="Dois elemento"
colecao.push("Mais um elemento","Mais n elementos")
colecao.each_match(/.*u.*/) {|r| puts r}
ou substituir os valores internos
colecao=Array.only String
colecao << "Um elemento"
colecao[1]="Dois elemento"
colecao.push("Mais um elemento","Mais n elementos")
colecao.each_gsub!(/elemento/,'coisa')