RUBY: 已定义?(klass) 看到局部变量而不是常量

RUBY: defined?(klass) seeing a local-variable instead of constant

我运行遇到一个问题,我需要检查class是否存在。但是,我 将 class 传递给变量 并尝试从那里检查它。

我的问题是我需要传递 defined?() 的实际常量才能工作,但我传递的是一个变量,所以它看到的不是常量,而是方法或变量。

obj 是一个 rails 模型实例,例如,特定的 User 或特定的 Car.

  def present(obj, presenter_class=nil, view_context=nil)
    klass = presenter_class || "#{obj.class}Presenter".constantize
    if defined?(klass) == 'constant' && klass.class == Class 
      klass.new(obj, view_context)
    else
      warn("#{self}: #{klass} is not a defined class, no presenter used")
      obj
    end
  end

撬输出:

[1] pry(ApplicationPresenter)> defined?(klass) 
=> "local-variable"

我尝试了下面的方法,但我得到了一个返回方法...

[18] pry(ApplicationPresenter)> defined?("UserPresenter".constantize)
=> "method"

我该如何解决这个问题?

嗯,显然 Object#defined? 没有达到您希望的效果。

tests whether or not expression refers to anything recognizable (literal object, local variable that has been initialized, method name visible from the current scope, etc.). The return value is nil if the expression cannot be resolved. Otherwise, the return value provides information about the expression.

你的目标看起来像是在重建布料机 gem 用 .decorate 所做的...不要忘记大多数 gem 都是开源的,你可以用它来自己尝试。参见示例 the decorator_class method from them

decorator_name = "#{prefix}Decorator"
decorator_name_constant = decorator_name.safe_constantize
return decorator_name_constant unless decorator_name_constant.nil?

他们使用方法 safe_constantize 并且当常量不可用时这显然 returns nil。

2.6.5 :007 > class UserPresenter; end;
 => nil 
2.6.5 :008 > 'UserPresenter'.safe_constantize
 => UserPresenter 
2.6.5 :009 > 'ForgottenPresenter'.safe_constantize
 => nil 

对我来说,这看起来正是您所需要的,而且它也是 safer than using constantize

  def present(obj, presenter_class=nil, view_context=nil)
    klass = presenter_class || "#{obj.class}Presenter".safe_constantize
    if klass != nil
      klass.new(obj, view_context)
    else
      warn("#{self}: #{klass} is not a defined class, no presenter used")
      obj
    end
  end