Adicionando funcionalidade ao Rails
-
09-06-2019 - |
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?
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
.