ruby的tap和try

最近发现很多时候都要判断 nil , 用了很多三元表达式,写起来总是感觉很重复,想起来以前看过关于 tap 和 try 的相关技巧,论坛里一些高手肯定也经常使用这个技巧,无奈自己经验尚浅,到现在才开始使用,特地仔细学习了下,希望能给新手朋友一点帮助

tap

tap 和 try 是 Rails 开发过程中两个很常用的方法,在调试和写出简洁代码上有着不错的发挥

从 tap 的 Api 可以看出,tap 是 Object 的 instance_method,传递 self 给一个 block,最后返回 self.

Object.instance_methods.grep /tap/
 => [:tap]

def tap     #tap 源码实现
  yield self
  self
end

用途一:调试。当你使用链式方法发生错误时,如果需要测试这个过程中哪出了问题,一般的做法是拆断这个方法,设置中间变量,接着测试中间变量是否正确,如果正确,则把变量换个地方继续测试,方法很长时就没法测了,当然 Ruby 为你想好了,有着优雅又简便的实现

%w(x y z).push('a').shift.tap {|x| p x }.upcase.next

输出每步的结果看看

(1..10)                .tap {|x| puts "original: #{x.inspect}"}
  .to_a                .tap {|x| puts "array: #{x.inspect}"}
  .select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"}
  .map { |x| x*x }     .tap {|x| puts "squares: #{x.inspect}"}

用途二:简化代码。我们构建一个方法想返回一个 String / Array / Hash 之类结果,一般的做法是先定义一个变量,结果把运算结果赋值给这个变量,接着返回变量,用 tap 一步搞定,其实就是源码意思的实现

[].tap {|i| i << "abc"}
''.tap {|i| i << do_some_thing }

try

try 可以让你调用对象方法时不用担心对象是nil并抛出异常,依旧先看源码(rails 3.2.8)

def try(*a, &b)
  if a.empty? && block_given?
    yield self
  else
    public_send(*a, &b) if respond_to?(a.first)
  end
end

def try(*args)
  nil
end

上面一个try是对 Object 的扩展,下面的是对 NilClass 的扩展,这就是为什么会nil不会抛出异常的原因,源码 .

try 如果只接受 block 则传递 self 给 block,返回 block 执行后的结果,否则就执行
public_send,public_send 与 send 的不同之处,public_send 只会 call public_method,看例子

@person && @persion.name
@person ? @person.name : nil

用 try 改写

@person.try(:name)
@person.try { |p| "#{p.first_name} #{p.last_name}" }

try 同样能接受参数、block,

@person.try(:find, 1)
@people.try(:collect) {|p| p.name}

新版ruby的&.与try相同

@people&.find(1)

通过源码可以看出 tap 和 try 两个小工具意思都非常明白,用起来也很简单方便,实乃居家简化好帮手

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341