Что делают $1.to_sym => args[0]
и ($1.to_sym,*args,&block)
в следующей строке кода?
class Table
def method_missing(id,*args,&block)
return as($1.to_sym,*args,&block) if id.to_s =~ /^to_(.*)/
return rows_with($1.to_sym => args[0]) if id.to_s =~ /^rows_with_(.*)/
super
end
# ...
end
Контекст:
Ruport - это библиотека отчетов на Ruby. Вы можете использовать класс Ruport :: Data :: Table для создания табличных данных и преобразования их в различные форматы - текст, например:
require 'ruport'
table = Ruport::Data::Table.new :column_names => ["country" , "wine" ], :data => [["France" , "Bordeaux" ], ["Italy" , "Chianti" ], ["France" , "Chablis" ]]
puts table.to_text
⇒
+--------------------+
| country | wine |
+--------------------+
| France | Bordeaux |
| Italy | Chianti |
| France | Chablis |
+--------------------+
Допустим, вы выбрали только французские вина и преобразовали их в значения, разделенные запятыми:
found = table.rows_with_country("France" )
found.each do |row|
puts row.to_csv
end
⇒
France, Bordeaux
France, Chablis
Вы только что вызывали метод с именем rows_with_country () в Ruport :: Data :: Table. Но как автор этого класса мог знать, что у вас будет столбец с именем country? Дело в том, что автор этого не знал. Если вы заглянете внутрь Ruport, вы увидите, что и rows_with_country (), и to_csv () являются призрачными методами. Класс Ruport :: Data :: Table в некоторой степени соответствует определению, приведенному выше.
Вызов rows_with_country () становится вызовом более традиционного метода, rows_with (: country), который принимает имя столбца в качестве аргумента. Кроме того, вызов to_csv () становится вызовом as (: csv). Если имя метода не начинается ни с одного из этих двух префиксов, Ruport возвращается к Kernel # method_missing (), что вызывает ошибку NoMethodError. (Вот для чего нужно ключевое слово super.)