不触发const_missing挂钩

时间:2017-08-15 13:45:43

标签: ruby constants

我将const_missing方法修补到Object和不同的上下文中:

auto_loader.rb

%w{../../lib ../../app}.each do |path|
  expanded_path = File.expand_path(path,__FILE__)
  $LOAD_PATH.unshift(expanded_path) unless $LOAD_PATH.include?(expanded_path)
end
class Object
def self.inherited(base)
    base.extend(Class_Methods)
    super
  end

  def const_missing(const)
    puts "loading(in Object) %s" % const.to_s
    path = const.to_s.split('::').compact.map(&:downcase).join('/') 
    require path
    self.const_get(const)
  end
  class << self
    def const_missing(const)
      puts "loading(in Object class << self) %s" % const.to_s
      path = const.to_s.split('::').compact.map(&:downcase).join('/') 
      require path
      self.const_get(const)
    end
  end
  module Class_Methods
    class << self
      def const_missing(const)
        puts "loading(in Class_Methods class << self) %s" % const.to_s
        path = const.to_s.split('::').compact.map(&:downcase).join('/') 
        require path
        self.const_get(const)
      end
    end



    def const_missing(const)
      puts "loading(in Class_Methods) %s" % const.to_s
      path = const.to_s.split('::').compact.map(&:downcase).join('/') 
      require path
      self.const_get(const)
    end

  end

  extend Class_Methods
end

当我运行代码时,我看到:

NameError: Uninitialized constant CONST

没有显示任何puts

我还用以下代码加载代码:

pry -r ./lib/auto_loader.rb

结果是一样的。

另一方面,如果我手动触发const_missing方法,我会看到loading(in Object) const

为什么const_missing挂钩没有被解雇?

1 个答案:

答案 0 :(得分:0)

您的示例不是最小的,也不会运行。如果我尝试以下操作它没有任何问题。我认为你的问题与其他问题有关。

class Object

  def self.inherited(base)
    base.extend(Class_Methods)
    super
  end

  def self.const_missing_impl(const, location)
    puts "loading(in #{location}) %s" % const.to_s
    path = const.to_s.split('::').compact.map(&:downcase).join('/') 
    puts "require #{path}"
  end

  def const_missing(const)
    Object.const_missing_impl(const, 'Object')
  end

  class << self
    def const_missing(const)
      Object.const_missing_impl(const, 'Object class << self')
    end
  end

  module Class_Methods
    def const_missing(const)
      Object.const_missing_impl(const, 'Class_Methods')
    end

    class << self
      def const_missing(const)
        Object.const_missing_impl(const, 'Class_Methods class << self')
      end
    end
  end

  extend Class_Methods
end

a = CONST1
b = a::CONST2
c = String::CONST3
d = Class_Methods::CONST4

# Prints
loading(in Object class << self) CONST1
require const1
loading(in Object class << self) CONST2
require const2
loading(in Object class << self) CONST3
require const3
loading(in Class_Methods class << self) CONST4
require const4