$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
您刚才所做的是在 Ruport::Data::Table 上调用名为 rows_with_country( ) 的方法。但是这个类的作者怎么会知道你会有一个名为 country 的列呢?事实是,作者并不知道这一点。如果您查看 Ruport 内部,您会发现 rows_with_country( ) 和 to_csv( ) 都是 Ghost 方法。Ruport::Data::Table 类有点像上面的定义。
对 rows_with_country( ) 的调用变成了对看起来更传统的方法 rows_with(:country) 的调用,它以列名作为参数。此外,对 to_csv( ) 的调用变成了对 as(:csv) 的调用。如果方法名不是以这两个前缀中的任何一个开头,Ruport 就会退回到 Kernel#method_missing(),这会抛出 NoMethodError。(这就是 super 关键字的用途。)