Method chaining - also die implementierung einer Methode durch verketten mehrerer anderer ist durch Ruby on Rails zu einer gewissen Popularität gelangt. Während sich Rails hier auf ein einfaches Namenschema und alias verlässt, bietet DataMapper hier eine Technik an, die sich vorzüglich für einen Ausflug in Rubys Objektmodell eignet. Diese Gelegenheit will ich nicht an mir vorüber gehen lassen und die Implementierung namens Chainable hier vorstellen.
Diesmal nur ein ganz kurzer. Über das Picky Lambda kann man gerne ewig lange diskutieren, aber mir ist gestern noch folgende, selten erwähnte Kleinigkeit aufgefallen: wenn man das picky lambda verwendet, können die Argumentklammern weggelassen werden.
1 2 |
f = -> a,b { puts a,b }
f[1,2] |
(Eigentlich will ich ja nur wissen, ob CodeRay damit zurecht kommt.)
Eine Weile (mehr als 4 Jahre) ist es inzwischen her, das Murphy hier zuletzt etwas zu rescue geschrieben hat. In der Erwartung, dass sich der Stoff inzwischen gesetzt hat, will ich hier zwei rescue-Varianten nochmal näher unter die Lupe nehmen: die Modifikator-Variante und die Methoden-Variante. Ist zwar kein Sonntag, aber hier mal wieder etwas Syntax.
Ruby 1.9.2 ist jetzt eine Weile draussen und mit Rails 3 empfiehlt nun auch das größte Ruby-Projekt seinen Einsatz. Daher werde ich mal den Syntax-Sonntag wieder aufleben lassen und ein paar der Neuigkeiten in 1.9.2 vorstellen. Erster Kandidat: die verbesserte String#%-Methode. Die hier verwendeten Beispiele stammen aus der Doku von Sven Fuchs i18n-Bibliothek.
Also, ich wusste schon, dass man folgendes schreiben kann, um Methoden mit beliebig vielen Argumenten zu definieren:
1 2 3 4 |
def bist_du_aber_klein(*) super essen(:vitamine) end |
Hier werden die restlichen Argumente einfach verworfen, und keiner lokalen Variable zugewiesen.
Der Stern kann auch noch in anderen Beziehungen auftauchen, zum Beispiel in Mehrfachzuweisungen oder bei Blockparametern:
1 2 |
gewinner, *nieten = die_anderen_gehen_leer_aus
array_von_arrays { |erstes, zweites, *rest| puts 'Was für ein Wetter!' } |
Interessanterweise kann man bei solchen Catch-all-Ausdrücken immer den Namen der Variable weglassen:
1 2 3 4 5 6 |
def gibs_mir *; end ja, * = nein, nein, nein obfusc do |*| end for key, * in ENV # puts(*) geht aber nicht! end |
In Ruby 1.9 geht auch:
1 2 3 4 5 6 7 |
a, *, b = *1..10 [a, b] #=> [1, 10] def letzter(*, last) last end letzter(*1..10) #=> 10 ENV.each.with_index { |(*, value), index| puts '%2d: %s' % [index, value] } |
Noch ein ganz extremes Beispiel, das nichts sinnvolles tut:
def***;%****%**;end;*a=*(a**a);b{|*|* =:*.*(:**)} |
Nützlich? Albern? Perl6? Eure Meinung!
Zucker für Syntax-Spielkinder, diesmal:
Ruby-Mine präsentiert lustige Kommas am Ende von Methodendefinitionen.
Nein, keine Litschi, sondern ein weiteres interessantes Detail der Ruby-Syntax.
Jawohl :)
class Feeling def ~ p :drunk end def ! p :alert end def -@ p :bad end def +@ p :good end end feeling = Feeling.new -feeling # => :bad +feeling # => :good !feeling # => :alert ~feeling # => :drunk # >> :bad # >> :good # >> :alert # >> :drunk
Der Fachmann/Die Fachmassaigiraffe sieht hier mehrere Dinge:
p gibt seine Argumente nicht nur aus, sondern auch zurück (statt nil.)matz sagt:
For good news, I have no big change left.
Dass man Methoden in Ruby auch groß schreiben darf, ist ja allgemein bekannt. Es gibt sogar Methoden wie Array, die genauso heißen wie eine Konstante. Die Namensräume von Konstanten und Methoden sind also getrennt.
Doch wie geht defined? damit um? Erkennt es, dass es zwei Objekte mit demselben Namen gibt?
# Ruby 1.8/1.9 Foo = 'Konstante' def Foo 'Methode' end Foo # => "Konstante" Foo() # => "Methode" defined? Foo # => "constant" defined? Foo() # => "method"
Also: Wenn man eine großgeschriebene Methode auf Existenz testen will, muss man Klammern dahinter setzen.
ruby -c
Is this Ruby? Yes!
Rails is for many in this world Fast Enough:
We got sites actually doing millions of dynamic
page views per day; amazing. Maybe you end
up being with the Yahoo or Amazon front page;
it's unlikely that an off-the-shelve framework
in ANY language will do you much good. You'
ll probably have to roll your own. But sure.
I'd like free CPU cycles too. I just happen
to care much more about free developer cycles
and am willing to trade the former for the
latter - What';s your opinion?
25 x warning: parenthesize argument(s) for future version
Syntax OK
Ich glaube, sowas geht echt nur in Ruby ^_^
Der Text ist von David Heinemeier Hansson, hab nur ein bisschen umformuliert.
Korrektur: PHP akzeptiert das natürlich auch. Weil kein <? drin vorkommt.
Syntax-Sonntag! Heute:
# Ich gehe bis zum Zeilenende. Eigentor.create :author => 'Petit' # ^_^ # Gibt eine zufällige natürliche Zahl zurück. def random_number 23 endRuby hat eine zweite, weniger bekannte Kommentar-Variante:
=begin = Mehrzeilige Kommentare * waren wohl ursprünglich für die Dokumentation vorgesehen * haben sich aber nicht durchgesetzt * man benutzt stattdessen RDoc-Kommentarblöcke mit vielen #. =end
Ziemlich unhandlich, wenn man einfach etwas auskommentieren möchte. Zudem kann man diese mehrzeiligen Kommentare nicht schachteln.
Häufig möchte man einen Ruby-Block ausklammern – ein if, ein def, eine Klasse. Wie macht man das am einfachsten?
Für why the lucky stiff ist die Sprache Ruby keine Konstante (nicht einmal ein Eigenvektor), sondern ein Spielzeug. Das sieht man an seinem jüngsten Blogeintrag auf RedHanded in der Kategorie bits, mit dem schönen Namen EigenCharges. Die Leser waren wie üblich begeistert bis schockiert, unter anderem cypher, der auch diesen Beitrag angestoßen hat. Zeit für den Syntax-Sonntag! Im Gegensatz zu Superman kommen wir allerdings nicht immer pünktlich.
Syntax-Sonntag! Heute:
Zeit für den Myntax-Mittwoch! Und zwar geht es um
Syntax-Sonntag, verspätet. Ich hatte bis eben noch Urlaub. Heute geht es, wie versprochen, um
Syntax-Sonntag! Heute geht es um Strings (Zeichenketten). Ruby hat einiges zu bieten: