Ruby:使用 class_eval 定义常量只能通过 const_get 找到,但不能直接通过 :: Lookup 找到

2024-04-25

给定一个 User 类:

class User
end

我想使用定义一个新常量.class_eval. So:

User.class_eval { AVOCADO = 'fruit' }
  1. 如果我尝试通过访问它User::AVOCADO, I get uninitialized constant User::AVOCADO, but User.const_get(:AVOCADO)作品。为什么?

  2. 如果我在 Rails Concern 中定义一个常量included方法并将关注点包含在User类,我可以通过常规访问它::抬头。例如:

module FruitConcern
  extend ActiveSupport::Concern

  included do
     AVOCADO = 'fruit'
  end

end

class User
  include FruitConcern
end

User::AVOCADO
=> 'fruit'

然而,查找源代码 https://github.com/rails/rails/blob/5aaaa1630ae9a71b3c3ecc4dc46074d678c08d67/activesupport/lib/active_support/concern.rb对于 ActiveSupport:: 关注,included只是将该块存储在实例变量中(@_included_block),然后它被覆盖append_features将会通知base.class_eval(&@_included_block).

所以,如果只是打电话User.class_eval同一个块,为什么User::AVOCADO当常量在其中定义时起作用included阻止,但当我打电话时不阻止User.class_eval { AVOCADO = 'fruit' }直接地?

  1. 奇怪的是(见这篇博文 https://thoughtbot.com/blog/constant-annoyance),当做User.class_eval { AVOCADO = 'teste' },看来 Ruby 也将常量泄漏到了顶层。所以:
User.const_get(:AVOCADO)
=> "fruit"
AVOCADO
=> 'fruit'

我知道块具有平面范围,但该常量未事先定义,并且我期望class_eval改变两者selfdefault definee到接收器。这里发生了什么?这个常量是如何在顶层和用户范围内定义两次的?


当您定义常量时,您并不是将常量分配给self。您正在当前模块嵌套中定义一个常量。

当您显式打开一个类或模块时,您还设置了模块嵌套:

module Foo
  BAR = 1
  puts Module.nesting.inspect # [Foo]
end

当你这样做时User.class_eval { AVOCADO = 'fruit' }模块嵌套是“Main”,也称为全局对象:

User.class_eval do
  ADVOCADO = 'Fruit'
  puts Module.nesting.inspect # []
end

块实际上并不改变模块嵌套。const_set另一方面,在另一个模块嵌套中定义一个常量。

Ruby 实际上并没有两次定义该常量。相反,当您使用 const_get 或引用常量而不显式使用范围解析运算符时,Ruby 将查看模块嵌套并将树向上遍历到全局范围:

class A
end
B = 'eureka'
A.const_get(:B) # 'eureka'

这就是您如何引用顶级常量而无需在它们前面加上::。但是当你使用User::ADVOCADO你明确引用了里面的常量User.

当谈到这个令人担忧的例子时,你误解了正在发生的事情。根本不是关于class_eval。您正在定义常数FruitConcern::AVOCADO.

当你然后包括FruitConcern into User你正在添加FruitConcern到包含在常量查找中的祖先链上:

module FruitConcern
  ADVOCADO = 'fruit'
end

class User
  include FruitConcern
end

User::ADVOCADO  # fruit

See:

  • Ruby 模块:包含、前置、扩展 https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073
  • 关于 Ruby 中的常量查找,您想了解的所有信息 https://cirw.in/blog/constant-lookup.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby:使用 class_eval 定义常量只能通过 const_get 找到,但不能直接通过 :: Lookup 找到 的相关文章

  • 设备注册控制器获取零资源的自定义操作

    基本上我想要有两个单独的操作来更改密码和更改电子邮件 而不是只有一个 我已经更新了我的路由以指向继承自 Devise RegistrationsController 的新控制器 我的路线 rb devise for users contro
  • 如何创建与 ActiveResource 对象的 ActiveRecord 关系?

    假设我正在为一家已经拥有 People 应用程序的出版公司编写一个图书馆应用程序 所以在我的图书馆应用程序中我有 class Person lt ActiveResource Base self site http api people m
  • ruby 的 String .hash 方法如何工作?

    我只是红宝石的新手 我见过一个字符串方法 String hash 例如 在irb 我试过了 gt gt mgpyone hash returns gt 144611910 这个方法是如何工作的 The hash方法是为所有对象定义的 看文档
  • kaminari ajax 分页不更新分页

    我正在使用 kaminari gem 在 Rails3 中实现分页 我一直在关注github上的这段代码https github com amatsuda kaminari example commits ajax https github
  • Ruby mp3 Id3 解析

    目前我正在从事一个音乐项目 处理用户 mp3 上传 问题是我找不到适用于所有文件的 id3 库 我努力了id3 ruby and Mp3Info库 但它们都没有给我一致正确的结果 例如 最常见的问题 错误的流参数 比特率和采样率 有时是持续
  • Rails 3 Mechanize - SocketError:getaddrinfo:主机或名称未知

    我正在使用 mechanize 但出现此错误 有人可以帮帮我吗 我已将元刷新设置为 true 错误日志 SocketError getaddrinfo Host or name not known form C Ruby192 lib ru
  • Rails 3.1+ 的 Jasmine 与 Mocha JavaScript 测试 [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对茉莉花有经验并且非常喜欢它 有谁有 Jasmine 和 Mocha 的经验 特别是 Rails 的经验吗 我想知道是否值得转用 我已经在 J
  • Rails 4 的 mobile_fu

    我正在尝试将我的应用程序从 Rails 3 2 13 切换到 Rails 4 在此过程中 我遇到了一个主要障碍 我使用 gem mobile fu 来确定用户是否来自移动设备 该 gem 需要 Railties 3 2 13 但 Rails
  • Rails 从 OrdersController 更新用户模型的属性

    这是我的代码 订单控制器类 def create order Order new params order if order purchase work GATEWAY store credit card options result wo
  • Capybara-webkit 无法处理与 bootstrap glyphicon 的链接

    我有一个链接 link to q span class glyphicon glyphicon trash span html safe feed item data confirm Are you sure toggle tooltip
  • Omniauth + Google + Faraday + 代理背后=如何设置代理?

    我的生产服务器是乌班图12 我在用着设计 OmniAuth处理 Google 身份验证 但是当 Google 将控件返回给我的应用程序时 我收到错误 网络不可达 我认为这是因为服务器位于代理后面 这是错误描述 Request URL htt
  • 如何在两个模型之间建立两个 has_many/belongs_to 关系?

    我有一个Project模型 以及一个Contact模型 项目模型有一个所有者和一个客户 两者都是Contacts 显然我遇到了一些不明确的事情 因为如果我有联系人并询问其项目 Rails 将不知道我询问的是它的项目是客户还是所有者 到目前为
  • 检查rails devise ldap gem中的组成员身份,是否在yaml中?

    我是否应该使用 ldap yml 文件来确保使用 ldap 进行身份验证的人拥有分配给他们的正确组以允许他们进入 无论如何 我都不是 AD 专业人士 这让我很困惑 什么是组和属性 据我了解 我们在 AD 中有一个用户 他们有一个 samAc
  • Rails - 安装 Spree 时出现问题

    我在 Rails 应用程序中安装 Spree 时遇到问题 当我运行 gem spree 时 按照说明http spreecommerce com documentation getting started html http spreeco
  • 无法使用 Rails 6 Actiontext 渲染 youtube 嵌入 iframe

    我已经设置了一个自定义嵌入模型 这样我就可以将 Instagram 或 YouTube 嵌入等内容添加到我网站上的 ActionText 内容中 它适用于 Instagram 嵌入 但不适用于 YouTube 作为参考 我要显示的 yout
  • Ruby gem 环境问题 - LoadError: no such file to load -- robots

    我正在尝试使用 anemone gem 编写一个爬虫 这需要 robots gem 不管出于什么原因 机器人绝对不会包括在内 这是我的一些环境信息 gem list d robots LOCAL GEMS robots 0 10 1 Aut
  • 在 mac os Sierra 上,卡在“设置 CocoaPods 主存储库”上

    转移到 mac os sierra 后 我完全格式化了我的 mac 现在每次运行时我都面临安装 cocoapods 的问题sudo gem install cocoapods pre一切都安装得很好 当我尝试安装 Pod 时 终端堆栈打开S
  • 使用 Passenger + Apache 相对于 Webrick 的优势

    我想说服我的管理层 使用 Apache 乘客设置是继续生产的方法 而不是使用 webrick 或 mongrel 我从网上找到了一些观点 如果您能添加您的想法 那将非常有帮助 因为这将有力地帮助我表达我的观点 欢迎提供技术细节 如果您有任何
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • rspec 中的模拟方法链

    有一系列方法可以获得user目的 我试图模拟以下内容以返回user in my Factory Girl current user AuthorizeApiRequest call request headers result 我可以模拟该

随机推荐