无法将实例变量的值从同一 class (Ruby) 中传递给另一个实例变量

Failed to pass the value of an instance variable to another from within the same class (Ruby)

这是我的代码。

class Dog

    attr_accessor :name
    attr_reader :breed, :age

    def initialize(name, breed, age)
        @name = name
        @breed = breed
        @age = age
        @distance_in_kms = []
    end

    def walk(distance_in_kms)
        @distance_in_kms << {distance: distance_in_kms}
    end

    def walked_distance 
       @walked_distance = @distance_in_kms.inject(0) {|sum, hash| sum + hash[:distance]}
    end

    def display_walks
        puts "#{@name} has had #{@distance_in_kms.length} walks and walked #{@walked_distance} kms today:"
        @distance_in_kms.each do |each_walk|
            puts "#{each_walk[:distance]} km"
        end
    end 

    #overriding to_s to print a meaningful representation of a class
    def to_s
        return "Dog: breed-#{@breed} name-#{@name}"
    end
end

doggo = Dog.new("Roy", "Labrador", 8)
doggo.walk(3)
doggo.walk(5)
doggo.walk(1)

puts doggo.name = "Dang"
puts doggo.breed
doggo.display_walks

我得到的结果是这样的

Dang
Labrador
Dang has had 3 walks and walked  kms today:
3 km
5 km
1 km

kms之前的期望值应该是9,一天中每次步行的总和。很明显,我的walked_distance方法做错了。我试图将数组 @distance_in_kms 的值传递给 @walked_distance,但没有成功,return 的值是 nil.But 我该怎么做才能解决这个问题,得到预期的结果?谢谢!!

puts "#{@name} has had #{@distance_in_kms.length} walks and walked #{@walked_distance} kms today:"

但是你永远不会调用代码来计算@walked_distance。添加新步行时更新它或在此处计算总距离(例如,通过调用 walked_distance

您必须调用方法来更新@walked_distance,例如:

def display_walks
    walked_distance # <------ This line
    puts "#{@name} has had #{@distance_in_kms.length} walks and walked #{@walked_distance} kms today:"
    @distance_in_kms.each do |each_walk|
        puts "#{each_walk[:distance]} km"
    end
end

或者更改walked_distance方法,直接从字符串插值调用:

def walked_distance 
   @distance_in_kms.inject(0) {|sum, hash| sum + hash[:distance]}
end

def display_walks
    puts "#{@name} has had #{@distance_in_kms.length} walks and walked #{walked_distance} kms today:"
    @distance_in_kms.each do |each_walk|
        puts "#{each_walk[:distance]} km"
    end
end

题外话,只是一个小改动来评估:
@walked_distance = @distance_in_kms.values.sum

我也可以一开始就这样做:

class Dog

    attr_accessor :name
    attr_reader :breed, :age

    def initialize(name, breed, age)
        @name = name
        @breed = breed
        @age = age
        @distance_in_kms = []
        @walked_distance = []
    end

    def walk(distance_in_kms)
        @distance_in_kms << {distance: distance_in_kms}
        @walked_distance = @distance_in_kms.inject(0) {|sum, hash| sum + hash[:distance]}
    end

    def display_walks
        puts "#{@name} has had #{@distance_in_kms.length} walks and walked #{@walked_distance} kms today:"
        @distance_in_kms.each do |each_walk|
            puts "#{each_walk[:distance]} km"
        end
    end 

    #overriding to_s to print a meaningful representation of a class
    def to_s
        return "Dog: breed-#{@breed} name-#{@name}"
    end
end

doggo = Dog.new("Roy", "Labrador", 8)
doggo.walk(3)
doggo.walk(5)
doggo.walk(1)

puts doggo.name = "Dang"
puts doggo.breed
doggo.display_walks

或使用class方法创建一个计数器,然后尝试link它到实例(虽然这是很长的路)

的确,理解变量范围对于初学者来说是一场真正的斗争。无论如何,非常感谢回答我问题的人。谢谢!