Ruby DSL:需要严格的方法可见性技术

时间:2013-10-19 20:34:47

标签: ruby-on-rails ruby metaprogramming activesupport

module Powers
 def outer_method name, &block
  puts "outer method works"
   yield 
  end 
 def inner_method name, &block
  puts "inner method works ONLY inside outer method"
  yield 
 end
end 
class Superman
 include Powers 
 def attack 
  outer_method "fly to moon" do 
   inner_method "take a dump" do 
    p "feels good and earth is safe"
   end
  end
  inner_method "take a dump" do 
   p "earth is doomed" 
  end 
 end 
Superman.new.attack

如何强制执行inner_method只能从outer_method内的上下文中调用并保存行星?

2 个答案:

答案 0 :(得分:1)

由于您在Powers中包含Superman,因此Powers方法被视为Superman类的方法,因此没有可以阻止它们的访问控制可以访问Superman中的任何其他方法,包括inner_method

答案 1 :(得分:1)

我真的不明白为什么你需要这个。但是这个“黑客”呢?

module Powers
  def outer_method(name, &block)
    puts 'outer method works'
    self.class.send :class_eval, <<-STR, __FILE__, __LINE__
      def inner_method(name, &block)
        puts 'inner method works ONLY inside outer method'
        yield
      end
    STR
    yield
  ensure
    self.class.send(:remove_method, :inner_method) if respond_to?(:inner_method)
  end
end

class Superman
  include Powers

  def attack
    outer_method 'fly to moon' do
      inner_method 'take a dump' do
        p 'feels good and earth is safe'
      end
    end
    inner_method 'take a dump' do
      p 'earth is doomed'
    end
  end
end