2013-04-25 17 views
5

Ich habe bemerkt, dass CSV-Klasse in Ruby einige Shortcut Schnittstellen (siehe http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html):Ruby: Klasse akzeptiert einen Block?

CSV    { |csv_out| csv_out << %w{my data here} } # to $stdout 
CSV(csv = "") { |csv_str| csv_str << %w{my data here} } # to a String 
CSV($stderr) { |csv_err| csv_err << %w{my data here} } # to $stderr 
CSV($stdin)  { |csv_in| csv_in.each { |row| p row } } # from $stdin 

Gibt es eine Möglichkeit, dies für meine eigenen Klassen zu tun? Ich implementiere ein DSL und das würde Code viel sauberer machen.

Antwort

6

Es ist keine Klasse. Es ist eine Methode, die auf Object definiert ist (obwohl es auch eine Klasse gibt, die mit demselben Name CSV aufgerufen wird). Das Dokument, das Sie verknüpft haben, ist irreführend. This erklärt es besser.

Sie können dies nicht mit einem Modul tun, aber Sie können eine Methode definieren, die einen Block nimmt.

1

Das von Ihnen gezeigte Beispiel ist keine Klasse, die ohne Methode aufgerufen wird. Im Gegenteil, es ist eine Methode, die ohne Klasse aufgerufen wird. sawa hat bereits explained wie es funktioniert.

Ruby 2.0 eingeführt Refinements.

Sie könnten verfeinern Object, um eine benutzerdefinierte Methode hinzuzufügen und verwenden Sie es wie im Beispiel aus Ihrer Frage.

Wenn Sie auf Ruby 1.9 feststecken, können Sie Affepatch statt Verfeinerung verwenden.

Aber Sie sollten zweimal überlegen, weil dies Ihren Code spaghettisch, prozedural und weniger objektorientiert machen könnte.

+0

Danke für den Link "Verfeinerung". –

+2

Der ganze Zweck von 'verfeinern' besteht darin, den Bereich zu kontrollieren, in dem der Affe-Patch sichtbar ist. Da diese CSV-Methoden von überall sichtbar sein sollen, ist es nicht sinnvoll, Verfeinerungen zu verwenden. –

Verwandte Themen