ruby-on-rails - 当以不同的方式编写时,范围解析在 ruby​​ 中的工作方式不同

标签 ruby-on-rails ruby ruby-on-rails-4.2

我在开发功能时遇到了这个问题。假设有以下代码:

case 1:
module Person
  module Employee 
    class Officer
      def self.print_class(obj)
        obj.is_a? Employee
      end
    end
  end
end

case 2:
class Person::Employee::Officer
  def self.print_class(obj)
       puts obj.is_a? Employee
  end
end

class Employee < ActiveRecord::Base
end

emp = Employee.last

我们有模型 Employee 。
现在
对于案例 1:
Person::Employee::Officer.print_class(emp) 给出“假”
对于案例 2:
Person::Employee::Officer.print_class(emp) 给出“真”
为什么会这样?

最佳答案

::是范围解析运算符。不同于 classmodule关键字它不会重新打开模块并正确设置模块嵌套。
例如:

TEST = "I'm in the global scope"

module Foo
  TEST = "I'm scoped to foo"
end


module Foo::Bar
  def self.test
    TEST 
  end

  def self.nesting
    Module.nesting
  end
end

puts Foo::Bar.test # "I'm in the global scope"
puts Foo::Bar.nesting.inspect [Foo::Bar]
这是因为模块嵌套是在定义时按词法解析的。当你这样做 module Foo::Bar该模块嵌套是全局范围 - 当您引用 TEST 时未解析为 Foo::TEST自从 Foo不在模块嵌套中。
在你的情况下 2 Employee解析为 ::Employee不是 Person::Employee .
因此,您应该始终显式嵌套类和模块,因为它将设置正确的模块嵌套并避免这些非常意外的模块查找。
TEST = "I'm in the global scope"

module Foo
  TEST = "I'm scoped to foo"
  module Bar
    def self.test
      TEST 
    end

    def self.nesting
      Module.nesting
    end
  end
end

puts Foo::Bar.test # "I'm scoped to foo"
puts Foo::Bar.nesting.inspect [Foo::Bar, Foo]

关于ruby-on-rails - 当以不同的方式编写时,范围解析在 ruby​​ 中的工作方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62934207/

相关文章:

ruby-on-rails - Rspec 3 如何测试 flash 消息

ruby-on-rails - 使用链接而不是按钮提交 Rails 4 表单

ruby-on-rails - Rails 4.2 - 性能问题

ruby-on-rails - 测试邮件列表软件的最佳方法是什么?

ruby-on-rails - 如何判断一个模型有一个空关系

javascript - 使用ajax将字符串传递给 Controller ​​中的对象

nitrousio - Rails 4.2beta 的 Rails 亚硝酸预览问题

ruby-on-rails - 如何在 .irbrc 中需要 gem,而不需要将其添加到 Rails Gemfile 中?

ruby-on-rails - Ruby、RoR、gmail 和 NET::SMTP

arrays - 如何在 Rails 4.2 表单中提交字符串数组