Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: class accepting a block?

Tags:

ruby

I've noticed that CSV class in Ruby has some shortcut interfaces (see http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html):

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

Is there a way to do this for my own classes? I am implementing a DSL and that would make code much more cleaner.

like image 323
user1179926 Avatar asked Apr 25 '13 07:04

user1179926


2 Answers

It is not a class. It is a method defined on Object (Although there is also a class called with the same name CSV). The doc you linked is misleading. This explains it better.

You cannot do it like that with a module, but you can define a method that takes a block.

like image 161
sawa Avatar answered Sep 30 '22 00:09

sawa


The example you showed is not a class called without a method. On the opposite, it is a method called without a class. sawa has already explained how it works.

Ruby 2.0 introduced Refinements.

You could refine Object to add a custom method and use it like in the example from your question.

If you're stuck on Ruby 1.9, you can use monkey patching instead of refining.

But you should think twice because this might make your code more spaghettish, procedural and less object-oriented.

like image 31
Andrey Mikhaylov - lolmaus Avatar answered Sep 30 '22 00:09

Andrey Mikhaylov - lolmaus