Pergunta

Estou trabalhando em um aplicativo Rails e pretendo incluir algumas funcionalidades de "Obtendo o nome do host ou IP em Ruby on Rails" que eu perguntei.

Estou tendo problemas para fazê-lo funcionar.Fiquei com a impressão de que deveria apenas criar um arquivo no diretório lib, então chamei-o de 'get_ip.rb', com o conteúdo:

require 'socket'

module GetIP
  def local_ip
    orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true  # turn off reverse DNS resolution temporarily

    UDPSocket.open do |s|
      s.connect '64.233.187.99', 1
      s.addr.last
    end
  ensure
    Socket.do_not_reverse_lookup = orig
  end
end

Eu também tentei definir GetIP como uma classe, mas quando faço o habitual ruby script/console, não consigo usar o local_ip método em tudo.Alguma ideia?

Foi útil?

Solução

Você não descreveu como está tentando usar o método, então peço desculpas antecipadamente se isso é algo que você já conhece.

Os métodos de um módulo nunca são usados, a menos que o módulo seja incluído em uma classe.Os métodos de instância em uma classe exigem que haja uma instância da classe.Você provavelmente deseja um método de classe.E o arquivo em si deve ser carregado, geralmente por meio da instrução require.

Se o código a seguir estiver no arquivo getip.rb,

require 'socket'

class GetIP
  def self.local_ip
    orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true

    UDPSocket.open do |s|
      s.connect '64.233.187.99', 1
      s.addr.last
    end
  ensure
    Socket.do_not_reverse_lookup = orig
  end
end

Então você poderá executá-lo dizendo:

require 'getip'
GetIP.local_ip

Outras dicas

require irá carregar um arquivo.Se esse arquivo contiver definições de classe/módulo, seu outro código agora poderá usá-las.Se o arquivo contém apenas código que não está em nenhum módulo, ele será executado como se estivesse no mesmo lugar que sua chamada 'require' (como PHP include)

include tem a ver com módulos.

Ele pega todos os métodos do módulo e os adiciona à sua classe.Assim:

class Orig
end

Orig.new.first_method # no such method

module MyModule
  def first_method
  end
end

class Orig
   include MyModule
end
Orig.new.first_method # will now run first_method as it's been added.

Há também extend que funciona como include, mas em vez de adicionar os métodos como instância métodos, adiciona-os como aula métodos, assim:

Observe acima, como quando eu quis acessar o first_method, criei um novo objeto de Orig aula.Isso é o que quero dizer com método de instância.

class SecondClass
  extend MyModule
end
SecondClass.first_method # will call first_method

Observe que neste exemplo não estou criando nenhum objeto novo, apenas chamando o método diretamente na classe, como se ele tivesse sido definido como self.first_method durante todo esse tempo.

Então aí está :-)

require e include são duas coisas diferentes.

require é carregar estritamente um arquivo uma vez a partir de um caminho de carregamento.O loadpath é uma string e esta é a chave usada para determinar se o arquivo já foi carregado.

include é usado para "misturar" módulos em outras classes. include é chamado em um módulo e os métodos do módulo são incluídos como métodos de instância na classe.

  module MixInMethods
    def mixed_in_method
      "I'm a part of #{self.class}"
    end
  end

  class SampleClass
    include MixInMethods
  end

  mixin_class = SampleClass.new
  puts my_class.mixed_in_method # >> I'm a part of SampleClass

Mas muitas vezes o módulo que você deseja misturar não está no mesmo arquivo que a classe alvo.Então você faz um require 'module_file_name' e então dentro da classe você faz um include module.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top