Estes exemplos são baseados em exemplos que mostrei ontem durante o curso de Rails, e mostram bem o que não se deve fazer com Ruby (fora sobrescrever o método “+” de um Fixnum para que ele calcule “-”).
Um destes exemplos acho até que o Thiago ja postou no RubyOnBr ontem ![]()
Mas seguem eles com algumas explicações …
def ambiguo puts "teste" end => nil ambiguo teste => nil ambiguo = 5 => 5 ambiguo => 5 ambiguo() teste => nil
Primeiro definimos um método de nome “ambiguo”, e logo depois chamamos este método para ter certeza que esta tudo bem, depois definimos uma variável de mesmo nome, e toda vez que escrevemos apenas “ambiguo” o Ruby lê o valor da variável, pois é uma variável de escopo local e tem precedência na tabela de localização …
Mas logo depois, tentamos novamente chamar o método passando parâmetro nenhum “()”, e o Ruby sabe que uma variável não pode receber parâmetros (OK, exceto no caso de uma Proc, mas vamos deixar isto para mais adiante), então ele traduz o comando “ambiguo()” para algo parecido com:
if self.respond_to? "ambiguo"
self.send("ambiguo")
else
ambiguo.call
end
Neste caso ja podemos também ver o que aconteceria se o exemplo fosse feito com uma proc, ela só seria chamada caso não existisse o método, para chamar a proc, precisaríamos digitar algo como “ambiguo.call”
Este tipo de situação só é possível por que no Ruby é impossível chamar um método de um objeto como acontece na maior parte das linguagens, o que acontece é que o Ruby manda mensagens para os Objetos
Mas podemos também complicar um pouco mais a história …
Vejam o exemplo abaixo, que mostra mais ou menos a mesma coisa que antes mais complicando um pouco mais a leitura, pois passa a variável “ambiguo” como parâmetro para a mensagem de nome “ambiguo”
irb(main):008:0> def ambiguo(par)
irb(main):009:1> puts %Q|só imprime #{par}|
irb(main):010:1> end
=> nil
irb(main):011:0> ambiguo "teste"
só imprime teste
=> nil
irb(main):012:0> ambiguo = "mesmo nome"
=> "mesmo nome"
irb(main):013:0> ambiguo ambiguo
só imprime mesmo nome
=> nil
irb(main):014:0>
Agora vamos passar para a parte realmente maluca ![]()
Vejam este exemplo …
irb(main):008:0>class Teste
irb(main):008:0> def qualquer(param)
irb(main):008:0> %Q{param = #{param}}
irb(main):008:0> end
irb(main):008:0>end
=> nil
irb(main):008:0>t = Teste.new
=> #<Teste:0x2e675c4>
irb(main):008:0>t.qualquer "coisa"
=> "param = coisa"
irb(main):008:0>Teste = "coisa"
(irb):21: warning: already initialized constant Teste
=> "coisa"
irb(main):008:0>t.qualquer Teste
=> "param = coisa"
irb(main):008:0>t1 = Teste.new
NoMethodError: undefined method 'new' for "coisa":String
from (irb):23
irb(main):008:0>class Teste
irb(main):008:0>end
TypeError: Teste is not a class
from (irb):24
irb(main):008:0>Teste = t.class
(irb):26: warning: already initialized constant Teste
=> Teste
irb(main):008:0>t1 = Teste.new
=> #<Teste:0x2e59b04>
Agora deem uma olhada neste código …
Principalmente os erros depois de “t1 = Teste.new” e “class Teste end”
O que isto quer dizer? que os nomes de classes que tanto utilizamos no Ruby, são apenas constantes que apontam para o objeto que representa aquelas classes …
O que prova mais uma vez, que tudo no Ruby são objetos, até mesmo as classes são objetos
Bom, acho que era isto por enquanto, se alguem conseguir uma explicação mais clara destes exemplos seja bem vindo
Tags: Ruby