2

我有这个使用带current_user助手的设计的应用程序。当我创建一个模块时,即使它从未发生过,在我提到它的归属之后也会变成current_usernil

class PagesController < ApplicationController
  include ModuleTest

  def index
    a_test_method
  end
end

ModuleTest

module ModuleTest
  extend ActiveSupport::Concern

  def a_test_method
    puts "(BEFORE)===========> #{current_user.inspect}"
    current_user = nil if false
    puts "(AFTER) ===========> #{current_user.inspect}"
  end
 end

输出:

(BEFORE)===========> #<User id: 1>
(AFTER) ===========> nil

但是,如果我删除/注释掉这一行# current_user = nil if falsecurrent_user仍然有效:

(BEFORE)===========> #<User id: 1>
(AFTER) ===========> #<User id: 1>

这会与惰性评估有关吗?

编辑

整个问题依赖于 Ruby 在未评估语句时如何定义变量:

2.3.4 (main):0 > defined? this_never_seen_variable_before
=> nil
2.3.4 (main):0 > this_never_seen_variable_before = "value" if false
=> nil
2.3.4 (main):0 > defined? this_never_seen_variable_before
=> "local-variable"
2.3.4 (main):0 >
2.3.4 (main):0 > this_never_seen_variable_before_2
   NameError: undefined local variable or method `this_never_seen_variable_before_2' for main:Object
from (pry):119:in `<main>'
2.3.4 (main):0 > this_never_seen_variable_before_2 = "value" if false
=> nil
2.3.4 (main):0 > this_never_seen_variable_before_2
=> nil
2.3.4 (main):0 >

这在下面是如何工作的?

4

1 回答 1

2
  1. current_user是 Devise 提供的辅助方法,不是局部变量。

  2. 没有名为current_user=. current_user = nil您可以通过更改为self.current_user = nil并看到它崩溃来证明这一点。但这与您的问题无关。

所以结果是,您current_user在 2 之间定义了一个局部变量puts,它隐藏了具有相同名称的辅助方法。

奇怪的是,虽然current_user = nil由于 没有被执行if false,局部变量仍然被定义,并且它的值被隐式设置为nil。这就是为什么你的第二个puts节目nil。即使您更改current_user = nilcurrent_user = :someone,您的第二个puts仍应显示nil

于 2017-12-01T05:53:56.153 回答