我写了一个小的.rb工具,它使用了“空白”?方法。如果希望直接由ruby调用,我希望程序继续运行。我用以下代码猴子修补了对象,但在Rails下运行时我不想猴子修补。我该怎么办?
class Object
def blank?
respond_to?(:empty?) ? (respond_to?(:strip) ? strip.empty? : !!empty?) : !self
end
end
答案 0 :(得分:4)
首先要记住的是,不建议直接用猴子修补类(即,打开类以定义新方法)。它可以工作,但不是很灵活,被认为是代码的味道。
一种更明智的猴子修补方法是在mixin中定义您的方法,然后将其包含在类中。
这也使您可以有条件地包括mixin。例如,Ruby Gems中的一个常见要求是仅在(已经)加载另一个库的情况下才实现或定义某些内容。一种常见的方法是检查是否已定义该库中的常量。例如,您可以这样做:
module PresenceExtensions
def blank?
respond_to?(:empty?) ? (respond_to?(:strip) ? strip.empty? : !!empty?) : !self
end
end
unless Module.const_defined?("Rails") || Object.method_defined?(:blank?)
Object.include PresenceExtensions
end
另一种常用技术是尝试加载宝石,然后仅在宝石不可用时添加替代的猴子补丁:
begin
require "active_support/core_ext/object/blank"
rescue LoadError
Object.include PresenceExtensions
end
该技术的优势在于,如果没有可用的宝石,则会立即告诉您,因此您不必担心加载顺序。
答案 1 :(得分:0)
默认情况下,Rails不应在运行时加载文件,除非默认情况下希望通过某种配置或初始化程序等通过某种方式进行配置。例如,如果此类定义仅位于您的lib/monkey.rb
内,Rails将不会除非您告知,否则不会自动加载。
如果使用pry
,则可以在rails控制台中对此进行测试。
只需:
rails c
# inside your console:
show-method Object.blank?
# this should show you the actual method definition which should be somthing
# like:
From: /Users/myself/.rvm/gems/ruby-2.5.1/gems/activesupport-4.2.10/lib/active_support/core_ext/object/blank.rb @ line 16:
Owner: Object
Visibility: public
Number of lines: 3
def blank?
respond_to?(:empty?) ? !!empty? : !self
end
但是,如果rails加载了您的lib文件,您将看到可以通过require
在控制台中强制使用的定义
require './lib/monkey.rb'
show-method Object.blank?
From: /Users/myself/some/rails/project/lib/monkey.rb @ line 2:
Owner: Object
Visibility: public
Number of lines: 4
def blank?
puts "this is a monkey patch"
respond_to?(:empty?) ? (respond_to?(:strip) ? strip.empty? : !!empty?) : !self
end