2017-01-23 4 views
1

Я хочу перебирать массив хэшей и печатать значения на терминале.Ruby - массив хашей - неопределенный метод «каждая» ошибка

В настоящее время получаю сообщение об ошибке:

main.rb:14:in `print': undefined method `each' for nil:NilClass (NoMethodError) 
from main.rb:22:in `<main>' 

Я желающему перебирать, а не что-то простое, как puts @transactions

Любые идеи, почему я получаю эту ошибку? Благодаря

class TestRun 
    @transactions = [ 
     {:repayment_number => 1, :repayment_amount => 224.34}, 
     {:repayment_number => 2, :repayment_amount => 241.50}, 
     {:repayment_number => 3, :repayment_amount => 135.04}, 
     {:repayment_number => 4, :repayment_amount => 91.00} 
    ] 

    def print() 
     @transactions.each do |t| 
     puts "#{t[:repayment_number]} - #{t[:repayment_amount]}" 
     end 
    end 

end 

@test = TestRun.new 
@test.print() 
+1

'@ transaction' определяется на основе Eigenclass' TestRun', а не экземпляров 'TestRun'. – cobaltsoda

ответ

2

The @transactions является nil, потому что он не инициализируются как переменный экземпляр. Метод initialize может быть использован для создания этого объекта при создании объекта класса.

Вам необходимо исправить свой код, чтобы использовать его.

class TestRun 
    def initialize 
    @transactions = [ 
     {:repayment_number => 1, :repayment_amount => 224.34}, 
     {:repayment_number => 2, :repayment_amount => 241.50}, 
     {:repayment_number => 3, :repayment_amount => 135.04}, 
     {:repayment_number => 4, :repayment_amount => 91.00} 
    ] 
    end 

    def print() 
     @transactions.each do |t| 
     puts "#{t[:repayment_number]} - #{t[:repayment_amount]}" 
     end 
    end 

end 

@test = TestRun.new 
@test.print() 
+1

«Метод initialize' используется для инициализации переменных экземпляра класса». - для этого он может быть использован, но его первоначальная цель далека от этого. – mudasobwa

+0

@ mudasobwa Согласен. То, что я упомянул, это один из способов сделать это. ** Ответ Кэри Свовеланда ** гораздо более объяснительный. – 31piy

+0

@mudasobwa так, какова первоначальная цель 'initialize'? – Stefan

5

Вы определили @transactions дважды, сначала, когда self равна TestRun, что делает его экземпляр переменная класса, то в методе print, когда self является экземпляром TestRun.new, что делает, что один в экземпляр переменной. Эти две переменные отличаются от @night и @day.

Вот три способа заставить ваш код работать (первые два предназначены только для образовательных целей).

сделать печати метод класса

class TestRun 
    puts "self at class level = #{self}" 
    @transactions = [ 
    {:repayment_number => 1, :repayment_amount => 224.34}, 
    {:repayment_number => 2, :repayment_amount => 241.50} 
    ] 
    def self.print 
    puts "self within self.print = #{self}" 
    @transactions.each do |t| 
     puts "#{t[:repayment_number]} - #{t[:repayment_amount]}" 
    end 
    end 
end 
    #=> self at class level = TestRun 
TestRun.print 
    #=> self within self.print = TestRun 
    # 1 - 224.34 
    # 2 - 241.5 

Доступ к переменной экземпляра класса внутри метода печати

class TestRun 
    @transactions = [ 
    {:repayment_number => 1, :repayment_amount => 224.34}, 
    {:repayment_number => 2, :repayment_amount => 241.50} 
    ] 
    def print 
    puts "self within print = #{self}" 
    self.class.instance_variable_get(:@transactions).each do |t| 
     puts "#{t[:repayment_number]} - #{t[:repayment_amount]}" 
    end 
    end 
end 

TestRun.new.print 
    #=> self within print = #<TestRun:0x007fcccb13f390> 
    # 1 - 224.34 
    # 2 - 241.5 

Определение @transactions в методе инициализации, что делает его переменная экземпляра

Это то, что сделал @ 31piy, и, скорее всего, то, что предназначено OP.

class TestRun 
    def initialize 
    puts "self within initialize = #{self}"  
    @transactions = [ 
     {:repayment_number => 1, :repayment_amount => 224.34}, 
     {:repayment_number => 2, :repayment_amount => 241.50} 
    ] 
    end 
    def print 
    puts "self within print = #{self}" 
    @transactions.each do |t| 
     puts "#{t[:repayment_number]} - #{t[:repayment_amount]}" 
    end 
    end 
end 

TestRun.new.print 
    #=> self within initialize = #<TestRun:0x007fcccb2ae988> 
    # self within print = #<TestRun:0x007fcccb2ae988> 
    # 1 - 224.34 
    # 2 - 241.5 
+0

Ответ от @ 31piy имеет неправильную формулировку и в целом просто слепо показывает «как обычно это делают другие люди». Спасибо, что поместили это замечательное объяснение здесь. Конечно, конечно. – mudasobwa