Y0Gi hat geschrieben:
poker hat geschrieben:Das first-class-functions in Ruby (wegen dem Objektsystem.) nicht möglich ist, ist klar.
Mag mir das mal jemand erklären?
hi Yogi.
Als erstes ist wichtig zu wissen, das Ruby total OOP ist. Dann muss man begreifen das man auf Attribute (~Variabeln) nicht zugreifen kann von außen. Solche Zugriffe werden über Methoden forciert
Wo wir auch schon die Antwort darauf haben warum bei Ruby die Klammern optional sind.
Aber der Reihe nach:
Folgendes geht nicht
Code: Alles auswählen
class MyClass
def initialize
@eggs = [NIL, 1]
end
end
c = MyClass.new
c.eggs
und wirft folgende exception:
test.rb:8: undefined method `eggs' for #<MyClass:0x29406f4 @eggs=[nil, 1]> (NoMe
thodError)
Nur die Instanz selbst hat zugriff auf seine Instanzvariablen. Außerhalb kann man nur über Methoden darauf zugreifen:
Code: Alles auswählen
class MyClass
def initialize
@eggs = [NIL, 1]
end
def eggs
@eggs
end
def eggs=(value)
@eggs = value
end
end
c = MyClass.new
p c.eggs
c.eggs = 1
p c.eggs
c.eggs=(42)
p c.eggs()
Ergibt:
[nil, 1]
1
42
Hier kann man auch schon sehen wie Ruby Arbeitet. ein `c.eggs` oder `c.eggs()` ruft die Methode lesend auf. Ein `c.eggs = ` oder `eggs=()` währe dann eine Forcierung einer Zuweisung.
Da obere Möglichkeit zu viel Schreibkram ist, nur für Variablen die man nur lesen oder etwas zuweisen möchte, gibt es dafür auch eine Kurzform:
Code: Alles auswählen
class MyClass
attr_accessor :eggs
def initialize
@eggs = [NIL, 1]
end
end
`attr_accessor ` erzeugt selbständig `eggs()` und `eggs=()`. Darüberhinaus gibt es noch `attr_reader` das nur die `eggs()` erzeugt und ein `attr_writer` das nur `eggs=()` erzeugt.
So, aufgrund dieses OOP-Designs hat man sich dann entschieden klammern optional zu machen. Aber durch diese Entscheidung, ist es nicht möglich Funktionen "direkt" (=über ihren Namen) als Referenzen rumzureichen. Das heißt aber nicht das Ruby nicht Funktionen höherer Ordnung unterstützt
IN Ruby muss man halt vorhandenen Funktionen (eigentlich Methoden, den Funktionen gibt es in dem Sinne nicht) in proc-objects umwandeln um sie rum zureichen.
Auch kann man für anonyme Funktionen in ruby Blöcken verwenden (Insofern hat birkenfeld mit seiner Aussage auch irgendwie recht. Er bedenkt aber nicht das Blöcke noch weiter mehr machen können als er in seinem Trivial beispiel zeigt).
folgendes Python Beispiel
würde in Ruby z.B. so gehen:
Code: Alles auswählen
def foo()
42
end
def bar(f)
f.call
end
p bar(self.method(:foo))
Nicht so schön wie first-class-funktionen aber naja, es geht und IMO überwiegen die anderen Vorteile in Ruby und das Klammern optional sind
/e