|
|||
def
definiert.
Methodennamen sollten mit einem Kleinbuchstaben beginnen. [Sie erhalten
nicht sofort eine Fehlermeldung, wenn Sie einen Großbuchstaben benutzen. Wenn
Sie aber die Methode aufrufen, denkt Ruby zuerst, dass es sich um eine
Konstante und nicht um einen Methodenaufruf handelt und könnte den Aufruf
falsch parsen.] Namen von Methoden, die für Abfragen zuständig
sind, enden oft mit einem ``?
'', so wie instance_of?
.
``Gefährliche'' Methoden oder solche, die den Empfänger modifizieren, können
auf ``!
'' enden. String
zum Beispiel stellt die Methoden
chop
und chop!
bereit. Die erste retourniert den veränderten
String; die zweite verändert den Empfänger.
``?
'' und ``!
'' sind die einzigen Sonderzeichen, die als
Suffices für Methodennamen erlaubt sind.
Nun, da wir einen Namen für unsere neue Methoden angegeben haben, sollten wir
einige Parameter deklarieren. Parameter sind einfach ein Liste von
Namen lokaler Variablen, die in Klammern angegeben werden. Einige
Beispiele für Methodendeklarationen sind
def myNewMethod(arg1, arg2, arg3) # 3 Argumente # Code für die Methode würde hier stehen end def myOtherNewMethod # Keine Argumente # Code für die Methode würde hier stehen end |
def coolDude(arg1="Miles", arg2="Coltrane", arg3="Roach") |
||
"#{arg1}, #{arg2}, #{arg3}." |
||
end |
||
|
||
coolDude |
» | "Miles, Coltrane, Roach." |
coolDude("Bart") |
» | "Bart, Coltrane, Roach." |
coolDude("Bart", "Elwood") |
» | "Bart, Elwood, Roach." |
coolDude("Bart", "Elwood", "Linus") |
» | "Bart, Elwood, Linus." |
return
.
def varargs(arg1, *rest) |
||
"Got #{arg1} and #{rest.join(', ')}" |
||
end |
||
|
||
varargs("one") |
» | "Got one and " |
varargs("one", "two") |
» | "Got one and two" |
varargs "one", "two", "three" |
» | "Got one and two, three" |
Array
zusammengefasst, das diesem Parameter zugewiesen
wird.
yield
auf.
def takeBlock(p1) if block_given? yield(p1) else p1 end end |
takeBlock("no block") |
» | "no block" |
takeBlock("no block") { |s| s.sub(/no /, '') } |
» | "block" |
Proc
-Objekt
konvertiert und dem Parameter zugewiesen.
class TaxCalculator |
||
def initialize(name, &block) |
||
@name, @block = name, block |
||
end |
||
def getTax(amount) |
||
"[email protected] on #{amount} = #{ @block.call(amount) }" |
||
end |
||
end |
||
|
||
tc = TaxCalculator.new("Sales tax") { |amt| amt * 0.075 } |
||
|
||
tc.getTax(100) |
» | "Sales tax on 100 = 7.5" |
tc.getTax(250) |
» | "Sales tax on 250 = 18.75" |
connection.downloadMP3("jitterbug") { |p| showProgress(p) } |
connection
der Empfänger,
downloadMP3
der Name der Methode, "jitterbug"
der
Parameter und das Zeugs zwischen den geschwungenen Klammern der assoziierte
Block.
Für Methoden von Klassen und Modulen ist der Empfänger der Name der Klasse oder
des Moduls.
File.size("testfile") Math.sin(Math::PI/4) |
self
, das aktuelle Objekt,
gesetzt.
self.id |
» | 537712200 |
id |
» | 537712200 |
self.type |
» | Object |
type |
» | Object |
self
ist) implementiert Ruby private Methoden. Private
Methoden dürfen nicht mit einem Empfänger aufgerufen werden, daher
müssen sie Methoden sein, auf die nur das aktuelle Objekt zugreifen kann.
Die optionalen Parameter folgen dem Methodenname. Gibt es keine
Doppeldeutigkeiten, kann man die Klammern um die Argumentliste herum auslassen,
wenn man eine Methode aufruft. [Andere Dokumentationen zu Ruby nennen
diese Methodenaufrufe ohne Klammern manchmal ``Befehle.''] Außer in
den simpelsten Fällen empfehlen wir das jedoch nicht -- es gibt einige
Probleme, über die man dabei stolpern kann. [Insbesonders muss
man Klammern verwenden, wenn ein Methodenaufruf selbst wieder Parameter eines
anderen Methodenaufrufs ist (außer, es ist der letzte Parameter).]
Unsere Regel ist einfach: Wenn Sie im Zweifel sind, verwenden Sie Klammern.
a = obj.hash # Das gleiche wie a = obj.hash() # das. obj.someMethod "Arg1", arg2, arg3 # Das gleiche wie obj.someMethod("Arg1", arg2, arg3) # mit Klammern. |
def five(a, b, c, d, e) |
||
"I was passed #{a} #{b} #{c} #{d} #{e}" |
||
end |
||
|
||
five(1, 2, 3, 4, 5 ) |
» | "I was passed 1 2 3 4 5" |
five(1, 2, 3, *['a', 'b']) |
» | "I was passed 1 2 3 a b" |
five(*(10..14).to_a) |
» | "I was passed 10 11 12 13 14" |
listBones("aardvark") do |aBone| # ... end |
if
oder while
angeben würden.
Manchmal jedoch möchte man etwas flexibler sein. Beispielsweise möchten wir
Mathematik lehren.[Natürlich müssten Andy und Dave zuerst einmal Mathe
lernen. Conrad Schneiker erinnerte uns daran, dass es drei Arten von
Leuten gibt: Die, die zählen können, und die, die's nicht können.]
Der Schüler könnte nach einer n-Additions- und einer
n-Multiplikationstabelle fragen. Fragt er nach einer
Multiplikationstabelle zur Zahl 2, würden wir 2, 4, 6, 8 usw. ausgeben (Dieser
Code überprüft die Eingabe nicht auf Fehler).
print "(t)imes or (p)lus: " times = gets print "number: " number = gets.to_i if times =~ /^t/ puts((1..10).collect { |n| n*number }.join(", ")) else puts((1..10).collect { |n| n+number }.join(", ")) end |
(t)imes or (p)lus: t number: 2 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 |
if
-Anweisung. Es wäre nett, wenn wir den Block,
der die Berechnung durchführt, ausklammern könnten.
print "(t)imes or (p)lus: " times = gets print "number: " number = gets.to_i if times =~ /^t/ calc = proc { |n| n*number } else calc = proc { |n| n+number } end puts((1..10).collect(&calc).join(", ")) |
(t)imes or (p)lus: t number: 2 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 |
Proc
handelt. Ruby entfernt das Argument von der Liste,
konvertiert das Proc
-Objekt in einen Block und
assoziiert ihn mit der Methode.
Diese Technik kann benutzt werden, um etwas ``syntactic sugar'' zur Verwendung
von Blöcken hinzuzufügen. Beispielsweise möchte man manchmal einen Iterator
nehmen und jeden Wert, den er mit yield
zurückgibt, in einem Array
speichern. Dafür verwenden wir unseren Fibonaccizahlen-Generator von Seite 42
nochmals.
a = [] |
||
fibUpTo(20) { |val| a << val } |
» | nil |
a.inspect |
» | "[1, 1, 2, 3, 5, 8, 13]" |
into
, die einen Block zurückgibt, der das Array füllt. (Beachten
Sie gleichzeitig, dass der zurückgegebene Block eigentlich ein Closure ist --
er referenziert den Parameter anArray, auch nachdem die Methode
into
beendet wurde.)
def into(anArray) |
||
return proc { |val| anArray << val } |
||
end |
||
|
||
fibUpTo 20, &into(a = []) |
||
a.inspect |
» | "[1, 1, 2, 3, 5, 8, 13]" |
SongList
einzubauen.
class SongList def createSearch(name, params) # ... end end aList.createSearch("short jazz songs", { 'genre' => "jazz", 'durationLessThan' => 270 } ) |
=>
Wert Paare in einer
Argumentliste angeben, solange sie jedem normalen Argument folgen und jedem
Array und Block vorangehen. All diese Paare werden in einem einzigen Hash
gesammelt und der Methode als ein Argument übergeben. Klammern werden nicht
gebraucht.
aList.createSearch("short jazz songs", 'genre' => "jazz", 'durationLessThan' => 270 ) |