Разве эти два фрагмента Ruby не должны работать одинаково? - PullRequest
2 голосов
/ 11 марта 2012

Занимаясь Ruby , я начал играть с такими вещами, как то, как Ruby возвращает последнее, что вы упомянули, даже если это не было после конструкции return.Однако, почему эти два фрагмента не работают одинаково? Разве они не должны?

module Enumerable
  def palindrome?
    reversed_self = self.reverse
    self.each_with_index {|el,index|
      unless self[index]==reversed_self[index]
        return false ## <-----
      end
    }
    true
  end
end

пока все хорошо: put ['foo', 'bar», 'Базь]. палиндром?выводит «false»

и

module Enumerable
  def palindrome?
    reversed_self = self.reverse
    self.each_with_index {|el,index|
      unless self[index]==reversed_self[index]
        false ## <------
      end
    }
    true
  end
end

выводит ['foo', 'bar', 'baz']. palindrome?печатает 'true' по какой-то причине

Какая наука стоит за этим?

Ответы [ 3 ]

3 голосов
/ 11 марта 2012

Ruby вернет значение последнего выполненного выражения в методе. false во второй версии не является последним выражением, нет ничего, что указывало бы Ruby на прекращение выполнения в этой точке, поэтому он будет продолжать процесс до тех пор, пока метод не завершится.

return - это способ явно сказать Ruby о прекращении выполнения и возвращении значения.

2 голосов
/ 11 марта 2012

Не совсем! return внутри блока отличается от return внутри лямбды, как упоминалось в моем ответе . Когда вы return из блока, вы возвращаетесь из всего метода, а не из блока.

Мы можем проиллюстрировать это следующим образом:

return :foo # => LocalJumpError: unexpected return
[1, 2, 3].map { return :foo } # => LocalJumpError: unexpected return
[1, 2, 3].map { :foo } # => [:foo, :foo, :foo]

Обычно этого не происходит с лямбдами:

l = lambda { return :foo }
l.call # => :foo
[1, 2, 3].map { l.call } # => [:foo, :foo, :foo]

Но когда мы пытаемся передать лямбду как блок методу, поведение снова меняется:

[1, 2, 3].map &l # => LocalJumpError: unexpected return
1 голос
/ 11 марта 2012

Если оператор return отсутствует, возвращаемое значение функции является последним оцененным значением.Во втором фрагменте последнее значение всегда равно true.

Первый фрагмент возвращается рано с false.Второй ничего не делает с этим false, он отбрасывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...