【问题标题】:How to access instance variable of a class with a module included within a class?如何使用包含在类中的模块访问类的实例变量?
【发布时间】:2015-09-11 12:30:55
【问题描述】:

我正在尝试通过修改 FrancePresident 类中的年龄方法来输出“59,bien sur”。我需要使用#{catchphrase} 来做到这一点。我尝试了很多方法,包括调用 self.age 。请参阅下面的代码 Rspec。

module Presidential
  attr_accessor :name, :age, :citizenship

  def initialize(name, age)
    @name, @age, @citizenship = name, age, self.class.citizenship
  end

end

class UnitedStatesPresident 
  include Presidential
   def self.citizenship
     "The United States of America"
   end
 end

class FrancePresident 
 include Presidential
 def name 
   name + ", #{catchphrase}"
 end
 def age
 end
 def citizenship
  "#{self.class.citizenship}, #{catchphrase}"
 end
 def self.citizenship
   "La France"
 end
 def catchphrase
   "bien sur"
 end
end

RSPEC
describe FrancePresident do
  describe "catchphrase" do
    it "sounds just right" do
      expect( FrancePresident.citizenship ).to eq("La France")
      sarcozy = FrancePresident.new("Nicolas Sarkozy", 59)
      expect( sarcozy.citizenship ).to eq("La France, bien sur")
      expect( sarcozy.age ).to eq("59, bien sur")
      expect( sarcozy.name ).to eq("Nicolas Sarkozy, bien sur")
    end
  end

  describe "inheritance" do
    it "should not inherit from President" do
      expect( FrancePresident.superclass.to_s ).not_to eq('President')
    end
  end
end

【问题讨论】:

  • 你不能创建一个模块的实例(一个模块没有new()方法),所以定义initialize()和实例变量是错误的。
  • 我不认为我创建了模块的实例。模块名称为“总统”

标签: ruby


【解决方案1】:

还有,这个:

 def name 
   name + ", #{catchphrase}"
 end

导致无限递归。 name() 是 getter,在 name() 中你调用 name()。在 getter(和 setter)中,您需要直接访问实例变量。

以下作品:

require 'rspec/autorun' 

module Presidential
  attr_accessor :name, :age, :citizenship

  def initialize(name, age)
    @name, @age, @citizenship = name, age, self.class.citizenship
  end
end



class UnitedStatesPresident 
  include Presidential

  def self.citizenship
    "The United States of America"
  end
end



class FrancePresident 
  include Presidential

  def name 
   "#{@name}, #{catchphrase}"
  end

  def age
    "#{@age}, #{catchphrase}"
  end

  def citizenship
    "#{self.class.citizenship}, #{catchphrase}"
  end

  def self.citizenship
    "La France"
  end

  def catchphrase
    "bien sur"
  end
end


RSpec.describe FrancePresident do
  describe "catchphrase" do
    it "sounds just right" do
      expect( FrancePresident.citizenship ).to eq("La France")
      sarcozy = FrancePresident.new("Nicolas Sarkozy", 59)
      expect( sarcozy.citizenship ).to eq("La France, bien sur")
      expect( sarcozy.age ).to eq("59, bien sur")
      expect( sarcozy.name ).to eq("Nicolas Sarkozy, bien sur")
    end
  end

  describe "inheritance" do
    it "should not inherit from President" do
      expect( FrancePresident.superclass.to_s ).not_to eq('President')
    end
  end
end

--output:--
$ ruby rspec_regular_ruby_code.rb 

Finished in 0.00159 seconds (files took 0.09554 seconds to load)
4 examples, 0 failures

【讨论】:

    【解决方案2】:

    age方法改成这样,

    def age
      "#{@age}, #{catchphrase}"
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 2011-10-03
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多