Am nächsten Ruby-Darstellung einer 'private static final' und 'public static final' - Klasse-variable in Java?
Angesichts der Java-code unten, was ist das nähste, das Sie darstellen könnte, diese beiden static final
Variablen in eine Ruby-Klasse? Und, ist es möglich, in Ruby zu unterscheiden zwischen private static
und public static
Variablen gibt es in Java?
public class DeviceController
{
...
private static final Device myPrivateDevice = Device.getDevice("mydevice");
public static final Device myPublicDevice = Device.getDevice("mydevice");
...
public static void main(String args[])
{
...
}
}
InformationsquelleAutor der Frage Hosh | 2010-03-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es wirklich keine entsprechende Konstrukt in Ruby.
Aber es sieht aus wie Sie machen eine klassische Portierung Fehler: Sie haben eine Lösung in die Sprache Ein und versuche zu übersetzen, in eine Sprache B, wenn, was Sie wirklich tun sollten, ist herauszufinden, die problem und dann herauszufinden, wie es zu lösen in der Sprache B.
Kann ich nicht wirklich sicher, was das problem ist, das Sie lösen möchten, aus, dass die kleinen codesnippet, aber hier ist eine mögliche Idee, wie die Implementierung in Ruby:
Hier ist eine andere:
(Der Unterschied ist, dass das erste Beispiel ist faul, es nur initialisiert die Instanz-variable, wenn das entsprechende Attribut Leser wird zuerst aufgerufen. Der zweite initialisiert, sobald die Klasse Körper ausgeführt wird, auch wenn Sie nie benötigt, genauso wie die Java-version läuft.)
Let ' s go über einige der Konzepte, die hier.
In Ruby, wie in jedem anderen "richtigen" (für unterschiedliche Definitionen von "richtig") - Objekt-orientierte Sprache, Zustand (Instanz-Variablen, Felder, properties, slots, Attribute, was immer Sie wollen, Sie zu nennen) ist immer private. Es ist keine Möglichkeitum Ihnen den Zugang von außen. Der einzige Weg, um die Kommunikation mit einem Objekt wird durch das senden von Nachrichten.
[Hinweis: immer, Wenn ich etwas schreiben wie "no way", "always", "der einzige Weg", usw., es ist eigentlich kein bedeutet "keine Möglichkeit, außer für Reflexion". In diesem speziellen Fall, es ist
Object#instance_variable_set
zum Beispiel.]In anderen Worten: in Ruby Variablen sind immer privat, der einzige Weg, um Zugang zu Ihnen ist über einen getter und/oder setter-Methode, oder, wie Sie genannt werden in Ruby, einem Attribut-reader und/oder writer.
Nun, ich halte über Sie zu schreiben Instanz-Variablenaber in dem Java-Beispiel haben wir statische Felderd.h. Klasse Variablen. Gut, in Ruby, die im Gegensatz zu Java sind die Klassen-Objekte zu. Sie sind Instanzen der
Class
Klasse und so, wie jedes andere Objekt, können Sie Instanzvariablen. Also, in Ruby, die äquivalent zu einer Klasse variable ist wirklich nur ein standard-Instanz-variable, die gehört zu einer Sache, die gerade passiert, zu einer Klasse.(Es gibt auch Klassen-Hierarchie-Variablen, gekennzeichnet mit einem doppelten at-Zeichen
@@sigil
. Die sind echt komisch, und man sollte sich wohl einfach ignorieren. Klassen-Hierarchie-Variablen sind über die gesamte Klassenhierarchie, d.h. die Klasse, zu der Sie gehören, alle Ihre Subklassen und Ihre Unterklassen und Ihre Unterklassen ... und auch alle Instanzen aller Klassen. Eigentlich sind Sie eher wie Globale Variablen als Klassenvariablen. Sie sollte wirklich genannt werden$$var
statt@@var
da Sie viel mehr eng mit der globalen Variablen als Instanz-Variablen. Sie sind nicht ganz nutzlos, aber nur sehr selten nützlich.)So, wir haben die "Feld" - Teil (Java-Feld == Ruby-Instanz-variable), wir haben die "öffentlichen" und "privaten" Teile (in Ruby -, Instanz-Variablen sind privat, wenn Sie möchten, um Sie der öffentlichkeit, eine öffentliche getter/setter-Methode), und wir haben die "statischen" Teil (Java-statisches Feld == Ruby-Klassen-Instanz-variable). Was ist mit den "letzten" Teil?
In Java, "Finale" ist einfach eine lustige Art, mit der Schreibweise "const", die die Designer vermieden werden, da die
const
Schlüsselwort in Programmiersprachen wie C und C++ ist subtil gebrochen, und Sie nicht wollen, um Leute zu verwirren. Ruby hat haben Konstanten (gekennzeichnet durch beginnend mit einem Großbuchstaben). Leider sind Sie nicht wirklich konstant, weil Sie versuchen, Sie zu ändern, während die Erzeugung einer Warnung, tatsächlich funktioniert. So, Sie sind eher eine Konvention als eine compiler-Regel durchgesetzt. Jedoch, die weitere wichtige Einschränkung der Konstanten ist, dass Sie sind immer öffentlich.Also Konstanten sind nahezu perfekt: Sie können nicht geändert werden (naja, Sie sollte nicht geändert werden), d.h. Sie sind
final
Sie gehören zu einer Klasse (oder Modul), d.h. Sie sindstatic
. Aber Sie sind immerpublic
so dass Sie leider nicht zur Modellierung verwendet werdenprivate static final
Felder.Und das ist genau der Punkt, wo denken über Probleme statt Lösungen kommt. Was ist es, was Sie wollen? Sie wollen Staat,
Erreichen Sie alle, aber in ganz anderer Weise als in Java:
||=
zusammengesetzte Zuweisung zuweisen nur einmalDas einzige, was Sie haben Grund zur Sorge, ist, dass Sie nicht zuordnen
@my_public_device
überall, oder besser noch, nicht auf. Verwenden Sie immer die get-Methode.Ja, das ist ein Loch in der Umsetzung. Ruby wird oft als eine "Erwachsene Sprache" oder eine "Erwachsene Sprache", was bedeutet, dass anstatt der compiler erzwingen bestimmte Dinge, die Sie gerade legen Sie Sie in die Dokumentation und einfach darauf zu Vertrauen, dass Sie Ihre Entwickler haben gelernt, dass die Berührung anderer Leute Geschlechtsteile ist unhöflich ...
Völlig verschiedenen Ansatz auf Privatsphäre, die in funktionalen Sprachen: Verschlüsse verwenden. Verschlüsse sind code-Blöcke, die dicht über Ihrer lexikalischen Umgebung, auch nach, dass die lexikalische Umgebung mehr Umfang. Diese Methode der Umsetzung von privaten Zustand ist sehr populär in Scheme, aber hat vor kurzem auch populär gemacht wurde von Douglas Crockford et al. für JavaScript. Hier ein Beispiel in Ruby:
Beachten Sie die feine, aber wichtige Unterschied zu den Versionen, an der Spitze meiner Antwort: das fehlen der
@
Siegel. Hier schaffen wir lokalen Variablen, nicht Instanz Variablen. Sobald der Rumpf der Klasse endet, werden diese lokalen Variablen fallen aus dem Rahmen und können nie aufgerufen werden, immer und immer wieder. Nur zwei Blöcke definieren, die die zwei getter-Methoden haben immer noch Zugang zu Ihnen, weil Sie dicht über den Klasse Körper. Jetzt sind Sie wirklich private und Siefinal
denn das einzige, was in der gesamten Programm, das hat immer noch Zugang zu Ihnen ist eine Reine getter Methode.Dies ist wahrscheinlich nicht idiomatischen Ruby, aber für jeden, der eine Lisp-oder JavaScript-hintergrund sollte deutlich genug sein. Es ist auch sehr elegant.
InformationsquelleAutor der Antwort Jörg W Mittag
Die nächste Sache, die ich an denken kann, um eine Finale variable ist die variable in der Frage, wie eine Instanz-variable eines Moduls:
Dieser Ausgänge:
Der trick hier ist, dass durch die Kapselung der Vorrichtung in einem Modul, können Sie nur auf das Gerät über das Modul. Aus der Klasse
Foo
gibt es keine Möglichkeit zu ändern die Gerät Sie zugreifen, ohne die direkte Einwirkung auf dieDevice
Klasse oder dieFinalDevice
Modul. Diefreeze
Anruf inFinalDevice
kann oder kann nicht angemessen sein, je nach Ihren Bedürfnissen.Wenn Sie möchten, eine öffentliche und private accessor, die Sie ändern können
Foo
wie diese:In dem Fall wirst du wohl ändern müssen
FinalDevice::get_device
zu nehmen, ein argument als gut.Update: @banister hat darauf hingewiesen, dass
@fin
wie erklärt, inFinalDevice
ist in der Tat zugänglich, die eine Instanz vonFoo
. Ich hatte aus Faulheit angenommen, da es nicht in die Standard-text-Ausgabe vonFoo#inspect
es war nicht im innerenFoo
.Können Sie Abhilfe schaffen, indem man mehr explizit machen
@fin
eine Instanz-variable von derFinalDevice
Modul:Die Ausgaben korrekt:
InformationsquelleAutor der Antwort Mark Rushakoff
Und ja,
require 'device'
wenn nötig.Obwohl Sie nichts mehr davon abhält, die Neudefinition der ständigen irgendwo sonst, außer einer Warnung 🙂
InformationsquelleAutor der Antwort alex.zherdev
private static in Ruby:
public static in Ruby:
Ruby kann nicht 'final' 🙂
InformationsquelleAutor der Antwort horseyguy