O mistério do define_method

7 respostas
N
class Here

    def initialize
        defineMe("RJ")
        defineMe("SP")
    end
       

    def defineMe(dest)
      define_method(dest) do
         puts "Going here #{dest}"
      end
   end
end

h = Here.new

Só que não funciona:

C:\>ruby here.rb
here.rb:10:in `defineMe': undefined method `define_method' for #<Here:0x2838220>
 (NoMethodError)
        from here.rb:4:in `initialize'
        from here.rb:16:in `new'
        from here.rb:16

Ouvi falar que tem que definir como self.defineMe, mas não consegui fazer funcionar de jeito nenhum.

Alguma mente caridosa poderia me explicar o que é “def self.defineMe” e como fazer isso funcionar?

7 Respostas

Mauricio_Linhares

[code=Ruby]
class Simple

def initialize

Simple.send( :define_method, 'my_method' ) do
  p "esse é o my method"
end

Simple.send( :define_method, 'my_other_method' ) do |first_param, second_param|
  p "esse é o outro metodo, parametros -> #{first_param} - #{second_param}"
end

end
end
novo = Simple.new

novo.my_method

novo.my_other_method( 1, 2 )
N

Eu entendi que o método define_method é um método estático (da classe).

Eu tentei fazer o método estático com self.defineMe e chamei Here.defineMe no initialize, mas não funcionou.

Por que o meu código não funciona?

Teria como modificá-lo para fazer ele funcionar?

Valeu mesmo Maurício !!! Você é o cara!

rubinelli
Estranho, isso aqui funcionou para mim:
class Here  
     
       def initialize  
           Here.defineMe("RJ")  
           self.class.defineMe("SP")  
       end  
            
     
       def self.defineMe(dest)  
          define_method(dest) do  
            puts "Going here #{dest}"  
        end  
     end  
  end  
     
  h = Here.new
  h.RJ
  h.SP
N

Aqui tb funcionou… Acho que fiz caca aqui então…

Mas me diz uma coisa self. antes do método transforma aquele método em estático, é isso?

Agora o interessante é que num método de instancia:

self.class.define_method não funciona.

Parece que ele é um método static protected, é isso?

pcalcado

Seu primeiro exemplo não funconou porque não existe o método define_method na instância, só existe na classe. O exemplo do Linhares funciona porque ele manda uma mensagem para a classe e não para o objeto, e com send() você pode acessar métodos privados. o exemplo do rubinelli funciona porque ele define um método público na classe que acessa o método privado para voc6e.

Fabio_Kung

Ele é um método das classes e privado.

Ser métodos das classes significa que ele está definido na classe Class:

class Class
  private
  def define_method(...) ... end
end

Não é como o ‘static’ do Java, mas você pode começar olhando assim.

rubinelli

Para explicar melhor, acontece o seguinte: Here é uma constante que aponta para um objeto da classe Class. Quando você faz “def Here.defineMe”, o runtime Ruby cria uma metaclasse para esse objeto, e insere o método que você especificou. A partir daí, quando você chama um método nesse objeto (que por acaso é do tipo Class), a metaclasse é a primeira a ser checada na árvore de herança para ver se existe esse método.

Criado 29 de fevereiro de 2008
Ultima resposta 2 de mar. de 2008
Respostas 7
Participantes 5