Hinzufügen von Funktionalität zu Rails
-
09-06-2019 - |
Frage
Ich arbeite an einer Rails-App und möchte einige Funktionen von „einbinden“Den Hostnamen oder die IP in Ruby on Rails abrufen"das habe ich gefragt.
Ich habe Probleme, es zum Laufen zu bringen.Ich hatte den Eindruck, dass ich einfach eine Datei im lib-Verzeichnis erstellen sollte, also nannte ich sie „get_ip.rb“ mit dem Inhalt:
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
Ich habe auch versucht, GetIP als Klasse zu definieren, mache aber das Übliche ruby script/console
, ich kann das nicht verwenden local_ip
Methode überhaupt.Irgendwelche Ideen?
Lösung
Sie haben nicht beschrieben, wie Sie die Methode anwenden möchten, daher entschuldige ich mich im Voraus, falls Sie das bereits wissen.
Die Methoden eines Moduls werden nie verwendet, es sei denn, das Modul ist in eine Klasse eingebunden.Instanzmethoden einer Klasse erfordern, dass eine Instanz der Klasse vorhanden ist.Wahrscheinlich möchten Sie stattdessen eine Klassenmethode.Und die Datei selbst sollte geladen werden, im Allgemeinen über die require-Anweisung.
Wenn sich der folgende Code in der Datei getip.rb befindet,
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
Dann sollten Sie es ausführen können, indem Sie sagen:
require 'getip'
GetIP.local_ip
Andere Tipps
require
lädt eine Datei.Wenn diese Datei Klassen-/Moduldefinitionen enthält, kann Ihr anderer Code diese jetzt verwenden.Wenn die Datei nur Code enthält, der in keinem Modul enthalten ist, wird sie ausgeführt, als ob sie sich an derselben Stelle befände wie Ihr „require“-Aufruf (wie PHP-Include).
include
hat mit Modulen zu tun.
Es übernimmt alle Methoden im Modul und fügt sie Ihrer Klasse hinzu.So was:
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.
Es gibt auch extend
was wie include funktioniert, aber anstatt die Methoden als hinzuzufügen Beispiel Methoden, fügt sie hinzu als Klasse Methoden, wie diese:
Beachten Sie oben, dass ich, als ich auf first_method zugreifen wollte, ein neues Objekt von erstellt habe Orig
Klasse.Das meine ich mit Instanzmethode.
class SecondClass
extend MyModule
end
SecondClass.first_method # will call first_method
Beachten Sie, dass ich in diesem Beispiel keine neuen Objekte erstelle, sondern nur die Methode direkt für die Klasse aufrufe, als wäre sie als definiert worden self.first_method
die ganze Zeit.
Hier bitteschön :-)
require
Und include
sind zwei verschiedene Dinge.
require
besteht darin, eine Datei unbedingt einmal aus einem Ladepfad zu laden.Der Ladepfad ist eine Zeichenfolge und dies ist der Schlüssel, der verwendet wird, um festzustellen, ob die Datei bereits geladen wurde.
include
wird verwendet, um Module in andere Klassen einzumischen. include
wird für ein Modul aufgerufen und die Modulmethoden sind als Instanzmethoden in der Klasse enthalten.
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
Aber oft befindet sich das Modul, das Sie einmischen möchten, nicht in derselben Datei wie die Zielklasse.Also machst du ein require 'module_file_name'
und dann machst du innerhalb der Klasse eine include module
.