如何在 Rails 中扩展 Object 类?

发布于 2024-11-04 11:51:26 字数 842 浏览 0 评论 0原文

我想将方法​​ nil_or_empty? 添加到所有类,因此我定义

module ObjectExtensions
  def nil_or_empty?
    return self.nil? || (self.respond_to?('empty?') && self.empty?)
  end
end
::Object.class_eval { include ::ObjectExtensions }

它在简单的 Ruby 脚本中工作正常

p nil.nil_or_empty? #=> true
p ''.nil_or_empty? #=> true
p [].nil_or_empty? #=> true
p 0.nil_or_empty? #=> false

但是,当我将它添加到我的库文件 lib/extensions.rb 在 Rails 3 应用程序中,似乎没有添加

NoMethodError (undefined method `nil_or_empty?' for nil:NilClass):
  app/controllers/application_controller.rb:111:in `before_filter_test'

我确实加载了库文件(该文件中的所有其他扩展都工作正常),

# config/application.rb
# ...
config.autoload_paths << './lib'

我在哪里错了?

I would like to add method nil_or_empty? to all classes, therefore I define

module ObjectExtensions
  def nil_or_empty?
    return self.nil? || (self.respond_to?('empty?') && self.empty?)
  end
end
::Object.class_eval { include ::ObjectExtensions }

It works fine in a simple Ruby script

p nil.nil_or_empty? #=> true
p ''.nil_or_empty? #=> true
p [].nil_or_empty? #=> true
p 0.nil_or_empty? #=> false

However, when I add it to my library file lib/extensions.rb in a Rails 3 app, it seems to be not added

NoMethodError (undefined method `nil_or_empty?' for nil:NilClass):
  app/controllers/application_controller.rb:111:in `before_filter_test'

I do load the library file (all other extensions from that file are working fine) and

# config/application.rb
# ...
config.autoload_paths << './lib'

Where am I wrong?

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

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

发布评论

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

评论(2

蓬勃野心 2024-11-11 11:51:26

首先,直接重新打开 Object 类会更干净:

class Object
  def nil_or_empty?
    nil? || respond_to?(:empty?) && empty?
    # or even shorter: nil? || try(:empty?)
  end
end

其次,告诉 Rails 自动加载 /lib 并不意味着 /lib 中的文件将在应用程序启动时加载 - 这意味着当您使用当前不存在的常量时定义后,Rails 将在 /lib 中查找与该常量对应的文件。例如,如果您在 Rails 应用程序代码中引用了 ObjectExtensions,并且尚未在某处定义它,则 Rails 会期望在 lib/object_extensions.rb 中找到它。

由于您无法像这样在 /lib 中扩展核心类,因此最好将核心扩展放在 config/initializers 目录中。当您的应用程序启动时,Rails 将自动加载其中的所有文件。因此,尝试将上述对象扩展放入 config/initializers/object_extension.rb 或 config/initializers/extensions/object.rb 或类似的东西中,一切都应该正常工作。

First, it's cleaner to just reopen the Object class directly:

class Object
  def nil_or_empty?
    nil? || respond_to?(:empty?) && empty?
    # or even shorter: nil? || try(:empty?)
  end
end

Second, telling Rails to autoload /lib doesn't mean that the files in /lib will be loaded when your app starts up - it means that when you use a constant that's not currently defined, Rails will look for a file in /lib corresponding to that constant. For example, if you referred to ObjectExtensions in your Rails app code, and it wasn't already defined somewhere, Rails would expect to find it in lib/object_extensions.rb.

Since you can't extend a core class in /lib like this, it's a better idea to put core extensions in your config/initializers directory. Rails will load all the files in there automatically when your app boots up. So try putting the above Object extension in config/initializers/object_extension.rb, or config/initializers/extensions/object.rb, or something similar, and everything should work fine.

画中仙 2024-11-11 11:51:26

在这种特殊情况下,您可以只使用 Rails 提供的 Object#blank?。对于相反的情况,有Object#present?

#blank? 与您的方法类似,但也将像 "   " 这样的全空白字符串视为空白。

In this particular case, you could just use the Rails-provided Object#blank?. For the inverse, there is Object#present?.

#blank? is like your method but also considers all-whitespace strings like "   " to be blank.

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