Blog do Urubatan
msgbartop
Desenvolvedor, Palestrante, Escritor, Nerd Assumido e Pai do Marcus :D
msgbarbottom

25 Sep 07 Ruby Quebra Cuca – Olha só como da para complicar …

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 :D
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 :D

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 :D
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 :D

Bom, acho que era isto por enquanto, se alguem conseguir uma explicação mais clara destes exemplos seja bem vindo :D

If you enjoyed this post, make sure you subscribe to my RSS feed!

Tags:

Leave a Comment