Ruby 初学者。实例变量未显示

Ruby beginner. Instance variable not showing

class Player
  def initialize (name, age, start_year)
    @name       = name.capitalize
    @age        = age
    @start_year = start_year
  end

  def playing_for
    current_year  = Time.new.strftime("%Y")
    num_of_years  = current_year - @start_year
    @num_of_years = num_of_years
  end

  def to_s
    "Hi, my name is #{@name}. I am #{@age} years old. I have been playing Ultimate for #{@num_of_years} years."
  end
end

jon = Player.new("jon", 41, 2009)
puts jon

当我在终端中运行上述代码时,它显示为:

Hi my name is Jon. I am 41 years old. I have been playing Ultimate for  years.

并且不显示 #{@num_of_years}

很明显我定义的方式有问题@num_of_years,但我不知道是什么。

@num_of_years 未打印,因为未设置变量(未初始化的实例变量的值为 nil 并且 "#{nil}" 导致空字符串)。

@name@age@start_year都设置在initialize中,调用Player.new调用,to_s调用通过 puts:

jon = Player.new("jon", 41, 2009) # <- "new" calls Player#initialize
puts jon                          # <- "puts" calls Player#to_s
另一方面,

@num_of_years 设置在 playing_for 中,它永远不会被调用(这就是 Wand Maker )。

您可以在调用 puts 之前手动调用该方法:(请记住通过将 strftime("%Y") 替换为 year 来修复

jon = Player.new("jon", 41, 2009)
#=> #<Player:0x007fab8a8aa448 @name="Jon", @age=41, @start_year=2009>
jon.to_s
#=> "Hi, my name is Jon. I am 41 years old. I have been playing Ultimate for  years."
jon.playing_for
#=> 7
jon.to_s
#=> "Hi, my name is Jon. I am 41 years old. I have been playing Ultimate for 7 years."

puts jon

打印:

Hi, my name is Jon. I am 41 years old. I have been playing Ultimate for 7 years.

但是每次都记住调用该方法很快就会变得乏味。

在初始化时设置@num_of_years更容易,就像其他实例变量一样:

class Player   
  def initialize (name, age, start_year)
    @name         = name.capitalize
    @age          = age
    @start_year   = start_year
    @num_of_years = Time.new.year - start_year
  end

  def to_s
    "Hi, my name is #{@name}. I am #{@age} years old. I have been playing Ultimate for #{@num_of_years} years."
  end
end

puts Player.new("jon", 41, 2009)
#=> Hi, my name is Jon. I am 41 years old. I have been playing Ultimate for 7 years.

或者您可以定义一种计算差异的方法。但是在这种情况下你不需要另一个实例变量,只需要 return 值:

class Player
  def initialize (name, age, start_year)
    @name         = name.capitalize
    @age          = age
    @start_year   = start_year
  end

  def playing_for
    Time.new.year - @start_year
  end

  def to_s
    "Hi, my name is #{@name}. I am #{@age} years old. I have been playing Ultimate for #{playing_for} years."
  end
end

puts Player.new("jon", 41, 2009)
#=> Hi, my name is Jon. I am 41 years old. I have been playing Ultimate for 7 years.

看看to_s方法。我已将 #{@num_of_years} 替换为 #{playing_for}