Zugriff auf Private Methoden von Modul-Funktionen in Ruby
Ich versuche zu schaffen private Hilfsmethoden für die Modul-Funktionen, ohne Erfolg. Ich fühle mich wie es ist etwas sehr einfaches, ich bin fehlt.
Aktualisiert, beispielsweise mit einem mehr nachvollziehbare use case:
module FancyScorer
module_function
def score(ary)
scores = []
ary.each_slice(2).with_index do |slice, i|
scores <<
case i % 2
when 0
score_eventh(ary)
else
score_oddth(ary)
end
end
scores.inject(:+)
end
private
def score_eventh(ary)
ary.inject(:+) / (ary.size - 1)
end
def score_oddth(ary)
ary.inject(:*) / (ary.size - 1)
end
end
FancyScorer.score([1,2,3,4])
# => `block in score_curiously': undefined method `score_eventh'
# for FancyScorer:Module (NoMethodError)
Hinweis: Die privaten Methoden sollte privat bleiben.
Hier der use case: es gibt mehrere Module, die enthalten verschiedene scoring-Techniken, z.B. FancyScorer
, SimpleScorer
, ComplexScorer
. Diese Funktionen sind unabhängig getestet und anschließend eingesetzt werden, um erstellen Sie eine score
Methode für verschiedene Klassen. Zum Beispiel:
class A
...
def score
FancyScorer.score(metrics) + 2*SimpleScorer.score(metrics)
end
end
class B
...
def score
0.5*FancyScorer.score(metrics) + 2*SimpleScorer.score(metrics[0,3]) + ComplexScorer.score(metrics)
end
end
Vorherigen Beispiel mit nicht vorgesehenen Anwendungsfall:
module Party
module_function
def pooper
enjoy
end
private
def enjoy
puts "Wahoo!"
end
end
Party.pooper
# => NameError: undefined local variable or method `enjoy' for Party:module
# from (party): in `pooper`
- Sie haben etwas von einem XY-problem hier. Erklären Sie Ihrem eigentlichen problem. Es ist krankhaft, um Methoden aufzurufen, die direkt auf einem Modul.
- Das Vorgestellte Beispiel war sehr gekünstelt. Ich bin der Umsetzung des design pattern gefördert von Corey Haines und Gary Bernhardt (was Bernhardt ruft "funktionale Kern und Imperativ shell"), und in bestimmten Fällen benötige ich die namespace-Konflikte zu vermeiden.
- Hast du jetzt bekommen?
- okay, so dass Sie versuchen, namespace, einige Dinge. Den code einfügen, müssen Sie nicht nachweisen, dass überhaupt. Warum nicht Sie zeigen einen Konflikt, den Sie versuchen zu vermeiden, so dass jemand kann Ihnen helfen, eine korrekte, idiomatische Lösung?
- Schnelle, einfache Frage zu stellen. Ich hatte nicht das Gefühl, es notwendig, Konvolut Beispiel mit einer speziellen Anwendungsfall. Du hast völlig Recht, über das Potenzial für Missbrauch. Ich werde zu aktualisieren, die Frage für die Nachwelt Willen, zu gegebener Zeit.
- Nun diese änderung nicht original post. Wenn Sie ändern die gesamte Antwort wird nutzlos sein. Wenn Sie über neue Verwirrungen,post eine neue Frage. Ich antwortete wie in obigen post,nicht an Ihr verändert.
- Ich versprach @naomik eine gründlichere Beispiel des use case. Die Frage bleibt unverändert: "ich versuche, erstellen Sie private helper-Methoden für die Modul-Funktionen."
Du musst angemeldet sein, um einen Kommentar abzugeben.
module_function(symbol,, ...) → self
sagt:-Müssen Sie sicherstellen, dass Sie erklären, die helper-Methode als
#private_class_method
:private
betrifft nur Instanz-Methoden.Darüber hinaus sollten Sie vorsichtig sein, über die Reihenfolge der Zugänglichkeit keywords wie
public
,private
, undmodule_function
. Diese überschneiden sich nicht, sondern überschreiben.Hinweis hier
module_function
überschreibt die vorherigenprivate
Erklärung.Hier einige weitere Beispiele, wenn
module_function
wird seinen job tun, und Wann nicht.Den
module_function
Definitionen stoppen, sobald ein anderes Zugänglichkeit keyword erscheint. In diesem Beispielmodule_function
unterbrochen durchpublic
machen#pooper
eine öffentliche Instanz-Methode. Verwendung vonprivate
würden ähnlich blockierenmodule_method
.Nun, wenn die Reihenfolge geändert wird:
Module#module_function
aber ich kann nicht sagen, ich bin überrascht. Dies ist eine funktionierende Lösung, aber es scheint sehr schlecht Moduls Zusammensetzung. (ps. Ich verstehe, das ist nicht Ihre Schuld, wie das ist, was der OP fragt nach)module_function
scheint wie ein guter Weg, zu fragmentieren, die Konsistenz des Moduls Verhalten und fügen Sie den Haufen von Komplexität. Ich müsste eine echte zwingenden Grund zu greifen, um es zu benutzen.Party#enjoy
ist immer noch aufrufbar.module_function
funktioniert.#enjoy
ist als private deklariert, später aber deklarierenmodule_function :enjoy
scheint außer Kraft setzen:Party.enjoy
ist jetzt ausführbar.Party#enjoy
ist als private deklariert, was bedeutet, ich sollte nicht in der Lage zu nennenParty.enjoy
von der öffentlichen Schnittstelle. Die Methode sollte nur zugänglich sein, von derpooper
Methode wie jede private Methode.