user9409769
user9409769

Reputation:

Why an obvious condition is not fulfilled?

I work on task about schedule and have class and .yml file where i want to retrieve data as "start" point, "end" point, "price" etc. And in my class I have method, where i want to determine if stations equal to user choice:

class Train 
  require 'yaml'

  def initialize(time)
    @time = YAML.load_file(time)
  end

  def calc(begin:, end:)
    ary = @time['time']
    start = begin
    stop = end
    res = []
    loop do
      tmp = ary.find { |h| h['begin'] == start }
      break unless tmp
      res << tmp
      start = tmp['end']
      break if start == stop
    end
  end
end

But it always fails on condition

break unless tmp

For example if write instance variable

a = Train.new("my_path_to yml") 
a.calc(begin: ':washington', end: ':tokyo')

It executes nothing. Even if I refactor loop block and write "for" iterator it throw "else" condition:

for i in ary
  if i['begin'] == 'washington'
    puts "good"
  else
    puts "no way"
  end
end

Here is my .yml file

time:
  -
    begin: :washington
    end: :briston
    time: 6
    price: 3
  -
    begin: :briston
    end: :dallas
    time: 4
    price: 2
  -
    begin: :dallas
    end: :tokyo
    time: 3.5
    price: 3
  -
    begin: :tokyo
    end: :chicago
    time: 3.5
    price: 3
  -
    begin: :chicago
    end: :dellawer
    time: 3.5
    price: 3

Thanks in advance!

Upvotes: 1

Views: 73

Answers (1)

iGian
iGian

Reputation: 11193

Try this change, check comments in code:

def calc(begin_:, end_:) # <-- don't call variables begin or end, they are reserved words
  ary = @time['time']
  start = begin_
  stop = end_
  res = []
  loop do
    tmp = ary.find { |h| h['begin'] == start }
    break unless tmp
    res << tmp
    start = tmp['end']
    break if start == stop
  end
  res # <-- return something
end

Call as:

train.calc(begin_: :washington, end_: :tokyo)
#=> [{"begin"=>:washington, "end"=>:briston, "time"=>6, "price"=>3}, {"begin"=>:briston, "end"=>:dallas, "time"=>4, "price"=>2}, {"begin"=>:dallas, "end"=>:tokyo, "time"=>3.5, "price"=>3}]


Take care not messing up strings with symbols.

  ary.each do |i| # for i in ary <-- pythonic! :)
    if i['begin'] == :washington # <-- should be a symbol to pass, not a string
      puts "good"
    else
      puts "no way"
    end
  end

Upvotes: 4

Related Questions