当左侧参数是一个类时,Ruby === 不按它的方式行事

发布于 2024-11-17 07:37:42 字数 1082 浏览 6 评论 0原文

我正在使用 Ruby 1.8.7 和 Rails 3.0.1,并且遇到一个问题,其根本原因似乎是“Array === object”操作。我之前在自己创建的类中看到了相同的行为,并通过不使用“===”运算符来围绕它进行编程(我认为我对 Ruby 的了解存在一些缺陷,这仍然相当有限)。但现在它发生在 ActionPack 内部,我需要对此采取一些措施。

当 FormHelper“fields_for”未按其应有的方式运行时,就会出现这种情况。以下视图代码片段(“<% %>”已删除以提高可读性):

form_for @coupon do |f|
  ...
  f.fields_for @coupon.participants do |cp|
    ...
  end
end

给出错误“ActionView::Template::Error(Array:Class 的未定义方法‘model_name’):” 在 form_for 辅助方法内。我确定它正在执行“case”命令的错误分支,设置断点并开始测试。结果如下:

/Library/Ruby/Gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/form_helper.rb:1152
case record_or_name_or_array
(rdb:1) pp record_or_name_or_array.instance_of? Array
true
(rdb:1) pp Array === record_or_name_or_array
false
(rdb:1) pp Array.object_id
2148267660
(rdb:1) pp record_or_name_or_array.class.object_id
2148267660

这非常明确地表明,虽然“record_or_name_or_array”绝对是一个数组,但“Array === record_or_name_or_array”返回 false。

顺便说一句,如果您怀疑“@f” .fields_for”是错误的语法,我尝试了带或不带“@f”的情况。并得到相同的结果。我还重新启动了 RoR 和我的机器,结果保持不变。

I'm using Ruby 1.8.7 with Rails 3.0.1 and am having a problem whose root cause appears to be the "Array === object" operation. I saw the same behavior before in a class of my own creation, and programmed around it by not using the "===" operator (I assumed that there was some flaw in my knowledge of Ruby, which is still rather limited). But now that it is happening inside ActionPack, I need to do something about it.

This surfaced when the FormHelper "fields_for" was not acting the way it should. The following view code snippet ("<% %>" removed to improve readability):

form_for @coupon do |f|
  ...
  f.fields_for @coupon.participants do |cp|
    ...
  end
end

gave the error "ActionView::Template::Error (undefined method `model_name' for Array:Class):"
inside the form_for helper method. I determined that it was executing the wrong branch of a "case" command, set a breakpoint and started testing. Here are the results:

/Library/Ruby/Gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/form_helper.rb:1152
case record_or_name_or_array
(rdb:1) pp record_or_name_or_array.instance_of? Array
true
(rdb:1) pp Array === record_or_name_or_array
false
(rdb:1) pp Array.object_id
2148267660
(rdb:1) pp record_or_name_or_array.class.object_id
2148267660

This shows pretty definitively that, while "record_or_name_or_array" is definitely an array, "Array === record_or_name_or_array" is returning false.

BTW, in case you're suspecting that "@f.fields_for" is the wrong syntax, I tried it both with and without the "@f." and got the same result. I have also restarted RoR and my machine and the results remain unchanged.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我为君王 2024-11-24 07:37:43

从控制台 (rails c) 尝试运行:

@coupon = Coupon.last
Array == @coupon.participants

如果该调用返回 false,则很可能您的关联设置不正确(即 has_many :participantsbelongs_to :优惠券)。

From the console (rails c) try running:

@coupon = Coupon.last
Array == @coupon.participants

If that call returns false, it is most likely that your associations are incorrectly setup (i.e. has_many :participants and belongs_to :coupon).

绝不服输 2024-11-24 07:37:43

@coupon.is_a? Array 应该返回 true,@coupon === Array 意味着 @coupon 等于 Array 的单例实例

@coupon.is_a? Array should return true, @coupon === Array would mean @coupon was equal to the singleton instance of Array

温柔戏命师 2024-11-24 07:37:42

试试这个:

@coupon = Coupon.last
Array === @coupon.participants #=> false
Array === @coupon.participants.find(:all) #=> true

关联 @coupon.participants 不是一个数组,它是一个代理。 activerecord-3.0.9/lib/active_record/associations/association_proxy.rb:25 中描述了 @coupon.participants.class == Array 为 true 的原因

添加:另一个有趣的实验是@coupon.participants.superclass。

Try this:

@coupon = Coupon.last
Array === @coupon.participants #=> false
Array === @coupon.participants.find(:all) #=> true

Association @coupon.participants is not an array, it is a proxy. The reason why @coupon.participants.class == Array is true is described in activerecord-3.0.9/lib/active_record/associations/association_proxy.rb:25

Added: Another interesting experiment would be @coupon.participants.superclass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文