Ruby 小白总结:在使用 Ruby 发现一些较为巧妙的写法

Canmel · 发布于 2016年12月27日 · 最后由 Artoria 回复于 2017年01月06日 · 2268 次阅读
29036
user = User.new

设定默认值

user.name ||= '默认值'

防止空指针

| 使用

area = Area.new
user.area = area
user.area&.area_name

| 使用delegate

delegate :area_name, to: :area, allow_nil: true

目标:使用format格式化user.balance,但为0时,为0,而不格式化

| user.balance = 23.027

user.balance.to_i.zero? ? format(‘%.2f’, user.balance) # to_i 可以防止空指针

捕获异常

使用rescue => ex 代替rescue StandardError => ex rescue => ex # 默认捕获StandardError, 推荐一般捕捉StandardError

if...else...end可以直接返回值

test = ''
if user.balance.to_i.zero?
  test = 'if值'
else
  test = 'else值'
end 

  ||

test = if user.balance.to_i.zero?
             'if值'
          else
             'else值'
          end

事务

ActiveRecord::Base.transaction do => transaction do

数组处理

user1 = User.new
user2 = User.new

| 目标:获取用户user的id 数组 我之前的写法是这样的

user_id_array = []
[user1, user2].each do |user|
   user_id_array << user1.id
end

||

user_id_array = [user1, user2].map(&:id)   # map() 提取数组某元素,组合成新的数组

字符串处理

| 变量和字符串的拼接 | user.name = '中国'

> ’我爱你‘ + user.name
> “我爱你中国”

||

> "我爱你#{user.name}"
> “我爱你中国”

有什么错误的还请各位前辈指出,有更为精美的代码还希望能给出一点,3q

共收到 20 条回复
17004
user_id_array = []
[user1, user2].inject(user_id_array) {|arr, user| arr << user.id; arr} 

还可以这样肛

29036

#1楼 @matrixbirds 哈,确实是哈,我没用过inject ,感觉这方法逻辑好奇葩😅

17004

#2楼 @Canmel hhh 我应该写reduce这样就不奇葩了。。

E55605

user_id_array = User.ids

29036

#4楼 @crazyphage 这是查询所有用户id的集合吧

4933

user.area&.area_name 这个是新版本里的用法吧

29036

#6楼 @realwol 空的话就使用&短路掉前面的,至于新与旧,我接触ruby时间不长,所以我也不知道这个新旧问题😜

A908ae

#7楼 @Canmel 2.3以前可以用active_support里的try,之前rubymine没有更新以前老是提示语法错误,还是用回了try

29036

#8楼 @adamshen 不知道是不是我这个是简写的原因呢? 在一个方法中想吃掉这个方法中所有的代码块的话能省掉

def xxx
  user.name
rescue => ex
  p 'xxxx'
end

相当于

def xxx
begin
  user.name
rescue => ex
  p 'xxx'
end
11222

捕获StandardError是很糟的做法,用异常来代替流程就更糟。其他的或多或少都有些毛病。先多看多学吧,至少把主要API和style guide过一遍。不着急总结,更不着急分享。

29036

#10楼 @billy 好的,谢谢 @billy 的意见, 😏  但是我们公司老大是说的要推荐捕获StandardError ,可能是我没有考虑清楚他的用意吧! 但是有一点我可能与你持有相反的态度,之前几年我是开发java的,因为公司需要,已经‘转行’一年了,看API,学习语言style 固然重要,但是闭门造车不是什么褒义词, 出来分享的话,第一点是想巩固下之前所学, 第二点是这里有很多大神在这个圈子,几个人就有几个风格,如果有大方出手指点一番也未尝不是好事。但是还是谢谢你的建议😀

4933

这个不是仅仅短路,他是新版本里的简写

29036

#12楼 @realwol  哦哦,不知道是从哪个版本开始的呢?

4933

#13楼 @Canmel 他这个方法是 a.present? && a.name.present? 这样的简写。版本的话是跟rails5一起的 >2.3吧。

6764
  1. Markdown 的语法还是要学习一下, 参考: https://www.zybuluo.com/mdeditor
  2. 相比较遗留代码中的 rescue Exception => e , rescue StandardError => e 稍好一些, 所以我推荐先改成 rescue => e. 更好地做法, 参考 Effective Ruby 中异常那一节.
  3. user.balance.to_i.zero? ? format(‘%.2f’, user.balance) 这个写法有点奇怪, 你再思考一下

@Canmel 童鞋是 Java 转过来的, 我刚刚开始带, 大家多多鼓励~

29036

#15楼 @42thcoder  是的!😜  user.balance.to_i.zero? ? format(‘%.2f’, user.balance)这句是有点怪,是这个样子的: 我之前可能比较关注的是在to_i那一块,这本来是个三目运算,后边我不是很关注他,就去掉了,贴过来感觉多余了😅

958

变量和字符串的拼接

> ['我爱你', user.name].join
> ['我爱你', user.name] * ''
> '我爱你' << user.name
> '我爱你'.concat(user.name)
> format('我爱你%s', user.name)
> '我爱你%s' % user.name
.......

还有其他的一些方法,当然执行效率是有差别的,也有些是rubocop不建议使用的,这里就不啰嗦了

其中,array#*(arg) 这个要复杂些,可以看下源码及DOC(http://ruby-doc.org/core-2.4.0/Array.html#method-i-2A)

96

#17楼 @zfjoy520 rubocop 是指哪种 ,新手求问

96

#9楼 @Canmel 可以直接

def xxx
rescue #可选
ensure #可选 不管是否发生异常是否捕获异常都会执行 (finally)
end

不过你写的相当于的那个形式少了一个end, 因为给了begin, rescue就跟着begin了,begin和def各自有一个end

说到单独用ensure有个套路 (可能用不到但会读到)

def foo  #不希望出现在异常回溯(backtrace)中的方法,如就是简单封装另一个方法bar
   bar
ensure
   $@.shift if $@ # $@是异常回溯的数组或nil(无异常发生),移除掉第一项(含有foo的这一项)
end
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册