Aggiunta di funzionalità a Rails
-
09-06-2019 - |
Domanda
Sto lavorando su un'app Rails e sto cercando di includere alcune funzionalità da "Ottenere il nome host o l'IP in Ruby on Rails" che ho chiesto.
Ho problemi a farlo funzionare.Avevo l'impressione che avrei dovuto semplicemente creare un file nella directory lib, quindi l'ho chiamato "get_ip.rb", con il contenuto:
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
Avevo anche provato a definire GetIP come classe, ma quando faccio il solito ruby script/console
, non sono in grado di utilizzare il file local_ip
metodo affatto.Qualche idea?
Soluzione
Non hai descritto come stai cercando di utilizzare il metodo, quindi mi scuso in anticipo se si tratta di cose che già conosci.
I metodi su un modulo non vengono mai utilizzati a meno che il modulo non sia incluso in una classe.I metodi di istanza su una classe richiedono che sia presente un'istanza della classe.Probabilmente vorrai invece un metodo di classe.E il file stesso dovrebbe essere caricato, generalmente tramite l'istruzione require.
Se il seguente codice è presente nel file 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
Quindi dovresti essere in grado di eseguirlo dicendo:
require 'getip'
GetIP.local_ip
Altri suggerimenti
require
caricherà un file.Se quel file contiene definizioni di classe/modulo, l'altro codice sarà ora in grado di utilizzarle.Se il file contiene solo codice che non è presente in nessun modulo, verrà eseguito come se fosse nello stesso posto della chiamata "require" (come PHP include)
include
ha a che fare con i moduli.
Prende tutti i metodi nel modulo e li aggiunge alla tua classe.Come questo:
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.
C'è anche extend
che funziona come include, ma invece di aggiungere i metodi as esempio metodi, li aggiunge come classe metodi, come questo:
Nota sopra, come quando volevo accedere a first_method, ho creato un nuovo oggetto di Orig
classe.Questo è ciò che intendo per metodo di istanza.
class SecondClass
extend MyModule
end
SecondClass.first_method # will call first_method
Nota che in questo esempio non sto creando nuovi oggetti, sto solo chiamando il metodo direttamente sulla classe, come se fosse stata definita come self.first_method
da sempre.
Quindi ecco qua :-)
require
E include
sono due cose diverse.
require
consiste nel caricare rigorosamente un file una volta da un percorso di caricamento.Il percorso di caricamento è una stringa e questa è la chiave utilizzata per determinare se il file è già stato caricato.
include
viene utilizzato per "mescolare" i moduli in altre classi. include
viene chiamato su un modulo e i metodi del modulo sono inclusi come metodi di istanza nella 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
Ma molte volte il modulo che desideri integrare non si trova nello stesso file della classe di destinazione.Quindi fai a require 'module_file_name'
e poi all'interno della classe fai un include module
.