Ruby默认赋值(|| =)vs Rescuing error

San*_*kai 5 ruby if-statement

由于a ||= 1相当于a || a = 1,可以说这是同义词糖:

if a.nil?
  a = 1
end
Run Code Online (Sandbox Code Playgroud)

同样,鉴于它session是类似哈希的对象,以下内容:

def increment_session_counter
  session[:counter] ||= 0
  session[:counter] += 1
end
Run Code Online (Sandbox Code Playgroud)

相当于:

def increment_session_counter
  if session[:counter].nil?
    session[:counter] = 0
  end
  session[:counter] += 1
end
Run Code Online (Sandbox Code Playgroud)

这是否意味着if每次在原始定义中都会执行隐式语句increment_session_counter?因为session[:counter]很可能nil只是第一次(即<< 1%的时间),我觉得以下代码更好,因为if每次都不会触发隐式:

def increment_session_counter
  session[:counter] += 1
rescue NoMethodError
  session[:counter] = 1
end
Run Code Online (Sandbox Code Playgroud)

这种代码在这种意义上是否更好?

话虽如此,我不知道如何Rescue在ruby中实现,以及它是否真的与可能带来的微小优化有关.

Ste*_*fan 3

session[:counter] += 1做了三件事:

  1. 获取值 ( Hash#[])
  2. 增加值 ( Integer#+)
  3. 存储增加的值 ( Hash#[]=)

这非常方便,但其简洁性也使其不灵活。

如果将步骤分开,提供默认值会容易得多:

def increment_session_counter
  session[:counter] = session.fetch(:counter, 0) + 1
end
Run Code Online (Sandbox Code Playgroud)