Ruby代码中caller[0]与正则表达式的匹配运行原理是什么?
匹配逻辑拆解
1. 先搞懂caller[0]是什么
Ruby 中caller是内核提供的方法,返回当前调用栈的回溯信息数组,数组的每一项都是固定格式的字符串:[文件绝对路径]:[调用行号]:in [调用方法名]'。你取的caller[0],就是**直接调用trxn_message的那一层栈信息**。 举个例子,如果你在def insert_record; trxn_message({name: 'test'}); end里调用这个方法,caller[0]的返回值大概是/xxx/project/test.rb:12:in insert_record'。
2. case + 正则的匹配规则
Ruby的case语句做分支判断时,用的是===运算符,当右侧分支是正则表达式、左侧是字符串时,正则 === 字符串等价于判断这个字符串是否能被正则匹配到,效果和你单独写caller[0] =~ /insert/是完全一致的。
对应你贴的代码逻辑:
- 只要
caller[0]的字符串里出现insert子串,就命中第一个分支,执行新增记录的打印逻辑 - 只要字符串里出现
find子串,就命中第二个分支,打印查询到的记录 - 只要字符串里出现
delete子串,就命中第三个分支,打印删除记录的提示 - 都不匹配就走空else分支,无任何输出
3. 优化建议
你当前的写法有小概率出现误匹配:如果调用栈的文件路径、行号里刚好包含insert/find/delete这几个字符串,哪怕上游方法名不包含也会进错分支。更稳妥的写法是先把上游方法名提取出来再匹配:
def trxn_message(attributes, records = nil) # 先提取上游方法名,捕获caller[0]里单引号包裹的内容就是方法名 upstream_method = caller[0][/`([^']+)'/, 1] case upstream_method when /insert/ binding.pry puts "#{post_trxn_count} new record created: #{attributes}" when /find/ binding.pry puts "#{records.count} records found with criteria #{attributes}" records.each {|r| puts r} when /delete/ binding.pry puts "#{post_trxn_count} records with criteria #{attributes} deleted" end end
内容的提问来源于stack exchange,提问作者RubyMiner
相关产品推荐
相关产品推荐

