Ich hatte Probleme mit Mixins, die Instanzmethoden enthalten und Methoden der Klasse. Dieser Code könnte einem Neuling helfen:
module Displayable
# instance methods here
def display
puts name
self.class.increment_displays
end
def self.included(base)
# This module method will be called automatically
# after this module is included in a class.
# We want to add the class methods to the class.
base.extend Displayable::ClassMethods
end
module ClassMethods
# class methods here
def number_of_displays
@number_of_displays # this is a class attribute
end
def increment_displays
@number_of_displays += 1
end
def init_displays
@number_of_displays = 0
end
# this module method will be called automatically
# after this module is extended by a class.
# We want to perform some initialization on a
# class attribute.
def self.extended(base)
base.init_displays
end
end
end
class Person
include Displayable
def name; @name; end
def initialize(name); @name=name; end
end
puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2
Zuerst dachte ich, ich könnte Module mit beiden Instanzmethoden haben und Methoden der Klasse, indem Sie dies einfach tun:
module Displayable
def display
puts name
self.class.increment_displays
end
def self.number_of_displays # WRONG!
@number_of_displays
end
[...]
end
Leider ist die Methode Anzahl_der_Anzeigen wird niemals aufgenommen oder erweitert, da es sich um eine "Modulklassenmethode" handelt. Nur "Modulinstanzmethoden" können in eine Klasse aufgenommen (als Instanzmethoden) oder in eine Klasse erweitert werden (als Klassenmethoden). Aus diesem Grund müssen Sie die Instanzmethoden Ihres Mixins in ein Modul und die Klassenmethoden Ihres Mixins in ein anderes Modul aufnehmen (die Klassenmethoden nehmen Sie normalerweise in ein Submodul "ClassMethods" auf). Dank der inklusive können Sie sowohl Instanzmethoden als auch Klassenmethoden mit einem einfachen "include Displayable"-Aufruf einbinden (wie im obigen Beispiel gezeigt).
Dieses Mixin zählt jede Anzeige auf einer pro Klasse Basis. Der Zähler ist ein Klassenattribut, so dass jede Klasse ihre eigene hat (Ihr Programm wird wahrscheinlich fehlschlagen, wenn Sie eine neue Klasse von der Klasse Person ableiten, da die @Anzahl_der_Anzeigen Zähler für die abgeleitete Klasse wird nie initialisiert). Vielleicht möchten Sie @Anzahl_der_Anzeigen von @@Anzahl_der_Anzeigen um ihn zu einem globalen Zähler zu machen. In diesem Fall wird jede Klassenhierarchie ihren eigenen Zähler haben. Wenn Sie einen globalen und eindeutigen Zähler wünschen, sollten Sie ihn wahrscheinlich zu einem Modulattribut machen.
All das war für mich nicht intuitiv, als ich mit Ruby anfing.
Ich kann immer noch nicht herausfinden, wie man einige dieser Mixin-Methoden sauber privat oder geschützt machen, obwohl (nur die Anzeige y Anzahl_der_Anzeigen Methode sollte als öffentliche Methode aufgenommen werden).
0 Stimmen
@phrases.insert(0, p) OK @phrases.insert(p) NICHTS passiert @phrases<<p # OK
0 Stimmen
Warum ist
true and false
true zurückgeben?3 Stimmen
Denn "x = wahr und falsch" wird eigentlich als "(x = wahr) und falsch" interpretiert. Das ist eine Frage des Vorrangs der Operatoren: "und" hat eine niedrigere Priorität als "=". Die meisten anderen Sprachen haben die umgekehrte Priorität, ich weiß nicht, warum sie diese Reihenfolge in Rails gewählt haben, ich finde es sehr verwirrend. Wenn Sie das "normale" Verhalten wollen, geben Sie einfach "x = (true und false)" ein, dann wird x falsch sein.
4 Stimmen
Eine andere Lösung ist die Verwendung von "&&" und "||" anstelle von "und" und "oder": Sie verhalten sich wie erwartet. Zum Beispiel: "x = true && false" führt dazu, dass x falsch ist.
0 Stimmen
"Das Prinzip der geringsten Überraschung bedeutet das Prinzip der geringsten mi Überraschung." aus de.wikipedia.org/wiki/Ruby_(Programmiersprache)#Philosophie Das Gleiche gilt für Python. Ich hatte ein ähnliches Zitat über den Schöpfer von Python, aber ich habe vergessen, wo es stand.
0 Stimmen
Array-Deklaration in Ruby