为什么我不能在class_eval块中访问局部变量?

时间:2015-07-16 17:44:17

标签: ruby

为什么我无法访问vehicle块中的变量class_eval

class Vehicle
  def self.number_of_wheels
    fail 'DEFINE in subclass'
  end

  def self.name
    fail 'DEFINE in subclass'
  end

  def self.define_methods
    number_of_wheels.times do |index|
      define_method("wheel_#{index}") do
        "This is wheel #{index} of #{self.class.name}"
      end
    end
  end
end

klasses = %w(
  tri_cycle
  motor_boat
).map do |vehicle| # THE VARIABLE I WANT TO ACCESS
  klass = Class.new(Vehicle)

  klass.class_eval do
    def self.number_of_wheels
      4
    end

    def self.name
      vehicle # using a string here will work
    end

    define_methods
  end

  klass
end

klasses.map { |k| k.new.wheel_1 } # => 
# ~> -:31:in `name': undefined local variable or method `vehicle' for #<Class:0x007ff6ea181800> (NameError)
# ~>    from -:13:in `block (2 levels) in define_methods'
# ~>    from -:40:in `block in <main>'
# ~>    from -:40:in `map'
# ~>    from -:40:in `<main>'

1 个答案:

答案 0 :(得分:3)

它被称为&#34;范围门&#34;。一旦方法,类或模块的定义开始,局部变量就会超出范围。有关更深入的信息,请参阅此书:https://pragprog.com/book/ppmetr2/metaprogramming-ruby-2

您可以使用define_methoddefine_singleton_method(适合您的任何内容)而不是def语法来绕过此问题(因为这将是方法调用,而不是方法定义)