Agregar funcionalidad a Rails
-
09-06-2019 - |
Pregunta
Estoy trabajando en una aplicación Rails y busco incluir algunas funciones de "Obtener el nombre de host o IP en Ruby on Rails" que le pregunté.
Tengo problemas para que funcione.Tenía la impresión de que debería crear un archivo en el directorio lib, así que lo llamé 'get_ip.rb', con el contenido:
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
También intenté definir GetIP como una clase, pero cuando hago lo habitual ruby script/console
, no puedo usar el local_ip
método en absoluto.¿Algunas ideas?
Solución
No has descrito cómo intentas utilizar el método, así que te pido disculpas de antemano si esto es algo que ya sabes.
Los métodos de un módulo nunca se utilizan a menos que el módulo esté incluido en una clase.Los métodos de instancia de una clase requieren que haya una instancia de la clase.Probablemente quieras un método de clase en su lugar.Y el archivo en sí debe cargarse, generalmente mediante la declaración require.
Si el siguiente código está en el archivo 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
Entonces deberías poder ejecutarlo diciendo:
require 'getip'
GetIP.local_ip
Otros consejos
require
cargará un archivo.Si ese archivo contiene definiciones de clase/módulo, entonces su otro código ahora podrá usarlas.Si el archivo solo contiene código que no está en ningún módulo, se ejecutará como si estuviera en el mismo lugar que su llamada 'require' (como PHP include)
include
tiene que ver con módulos.
Toma todos los métodos del módulo y los agrega a su clase.Como esto:
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.
También hay extend
que funciona como lo hace include, pero en lugar de agregar los métodos como instancia métodos, los agrega como clase métodos, como este:
Tenga en cuenta arriba, cómo cuando quise acceder a first_method, creé un nuevo objeto de Orig
clase.Eso es lo que quiero decir con método de instancia.
class SecondClass
extend MyModule
end
SecondClass.first_method # will call first_method
Tenga en cuenta que en este ejemplo no estoy creando ningún objeto nuevo, simplemente invoco el método directamente en la clase, como si hubiera sido definido como self.first_method
todo el tiempo.
Ahí vas :-)
require
y include
son dos cosas diferentes.
require
es cargar estrictamente un archivo una vez desde una ruta de carga.La ruta de carga es una cadena y esta es la clave utilizada para determinar si el archivo ya se ha cargado.
include
se utiliza para "mezclar" módulos en otras clases. include
se llama en un módulo y los métodos del módulo se incluyen como métodos de instancia en la clase.
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
Pero muchas veces el módulo que desea mezclar no está en el mismo archivo que la clase de destino.Entonces haces un require 'module_file_name'
y luego dentro de la clase haces un include module
.