在Ruby中使用模块中的实例变量

时间:2014-04-23 20:37:47

标签: ruby scope mixins

以下是我希望能够支持的脚本示例:

class Testing
  include Dialect

  url_is 'http://localhost:9292'
end

@page = Testing.new
@page.view

这里要注意的事项是:

  1. 我包括一个Dialect模块。 (代码如下所示。)
  2. 我直接在类上调用url_is()方法。
  3. 我在类的实例上调用了一个view()方法。
  4. url_is()方法将设置@url变量。理想情况下,view()方法可以读取该变量。这就是我似乎无法做到的。以下是支持上述脚本的代码:

    module Dialect
      module Generator
        module Assertion
          def url_is(url)
            @url = url
          end
        end
      end
    end
    
    module Dialect
      def self.included(caller)
        caller.extend Dialect::Generator::Assertion
      end
    
      def view
        puts "#{@url}"
      end
    end
    

    在这里你可以看到,当包含Dialect时,我有一个包含扩展我的Assertion模块的方法。这允许url_is()工作,url_is()确实设置实例变量。您还可以看到我定义了view(),我希望能够访问该@url变量。

    后一部分没有发生。我明白为什么我试图从Dialect模块中的Dialect :: Generator :: Assertion模块读取一个变量,但我不确定最好的方法是允许这个。

    我调查了module and class variable scopeRuby mixins and instance variables,但我没有找到任何可以确定处理我所描述情况的内容。

1 个答案:

答案 0 :(得分:2)

我认为您对类实例变量 @view感到困惑。

当您访问实例变量时,"实例"提到的是self。在实例方法中,self是类的实例(正如您所期望的那样)。在一个类中,self是类本身(Class的一个实例)!这应该说明区别:

class Foo
  @x = 0

  def initialize
    @x = 1
  end

  def self.x
    @x
  end

  def x
    @x
  end
end

Foo.x # 0
Foo.new.x # 1
Foo.x # still 0, they are entirely separate variables

扩展Dialect::Generator::Assertion时,url_is作为类方法添加到Test,因此@url被设置为Test本身的实例变量。但是当您添加Dialect时,view会作为实例方法添加到Test,因此它正在访问的@url用于{em>实例 { {1}}。

Test方法中,您只需指定需要变量的类版本

view