2013-04-25 17 views
5

Zauważyłem, że klasa CSV w Ruby ma kilka interfejsów skrótu (patrz http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html):Ruby: klasa przyjmująca blok?

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 

Czy istnieje sposób, aby to zrobić dla moich własnych klas? Wdrażam DSL, co znacznie uprości kod.

Odpowiedz

6

To nie jest klasa. Jest to metoda zdefiniowana na Object (chociaż istnieje również klasa o nazwie o tej samej nazwie CSV). Dokument, który łączysz, jest mylący. This wyjaśnia to lepiej.

Nie można tego zrobić za pomocą modułu, ale można zdefiniować metodę, która przyjmuje blok.

1

Podany przykład nie jest klasą wywoływaną bez użycia metody. Przeciwnie, jest to metoda nazywana bez klasy. sawa ma już explained jak to działa.

Ruby 2.0 wprowadziła Refinements.

Możesz poprawić wartość Object, aby dodać niestandardową metodę i użyć jej tak, jak w przykładzie z Twojego pytania.

Jeśli utkniesz w Rubim 1.9, możesz użyć łatania małpy zamiast rafinacji.

Ale powinieneś pomyśleć dwa razy, ponieważ może to spowodować, że twój kod będzie bardziej spójny, proceduralny i mniej obiektowy.

+0

Dzięki za link "Udoskonalenie". –

+2

Celem 'refine' jest kontrolowanie zakresu, w którym widoczny jest patch małpy. Ponieważ chcesz, aby te metody "CSV" były widoczne z każdego miejsca, nie ma sensu używać udoskonalenia. –

Powiązane problemy