Вы можете определить блок, встроенный в ruby? - PullRequest
3 голосов
/ 29 июля 2009

Можно ли определить блок во встроенном выражении с помощью ruby? Примерно так:

tasks.collect(&:title).to_block{|arr| "#{arr.slice(0, arr.length - 1).join(", ")} and #{arr.last}" }

Вместо этого:

titles = tasks.collect(&:title)
"#{titles.slice(0, titles.length - 1).join(", ")} and #{titles.last}"

Если вы сказали tasks.collect(&:title).slice(0, this.length-1) как вы можете сделать так, чтобы 'this' ссылался на полный массив, который был передан slice ()?

По сути, я просто ищу способ передать объект, возвращенный из одного оператора, в другой, не обязательно повторяя его.

Ответы [ 4 ]

4 голосов
/ 29 июля 2009

Вы путаете передачу возвращаемого значения в метод / функцию и вызов метода для возвращаемого значения. Способ сделать то, что вы описали, таков:

lambda {|arr| "#{arr.slice(0, arr.length - 1).join(", ")} and #{arr.last}"}.call(tasks.collect(&:title))

Если вы хотите сделать это так, как пытались, самое близкое совпадение - instance_eval, что позволяет запустить блок в контексте объекта. Так что будет:

tasks.collect(&:title).instance_eval {"#{slice(0, length - 1).join(", ")} and #{last}"}

Однако я бы не стал делать ни один из них, поскольку он длиннее и менее читаем, чем альтернатива.

1 голос
/ 29 июля 2009

Я не совсем понимаю, почему вы этого хотите, но вы можете добавить функцию к классам ruby, которая принимает блок и передает себя в качестве параметра ...

class Object
  def to_block
    yield self
  end
end

В этот момент вы сможете звонить:

tasks.collect(&:title).to_block{|it| it.slice(0, it.length-1)}

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

1 голос
/ 29 июля 2009

Я не совсем уверен, что вы пытаетесь сделать, но:

Если вы сказали tasks.collect (&: title) .slice (0, this.length-1), как вы можете сделать так, чтобы 'this' ссылался на полный массив, который был передан slice ()?

Используйте отрицательное число:

tasks.collect(&:title)[0..-2]

Также в:

"#{titles.slice(0, titles.length - 1).join(", ")} and #{titles.last}"

Я думаю, что с вашими цитатами происходит что-то странное.

0 голосов
/ 30 июля 2009

Хотя здесь есть много хороших ответов, возможно, вы ищете что-то более похожее на цель:

class Array
  def andjoin(separator = ', ', word = ' and ')
    case (length)
    when 0
      ''
    when 1
      last.to_s
    when 2
      join(word)
    else
      slice(0, length - 1).join(separator) + word + last.to_s
    end
  end
end

puts %w[ think feel enjoy ].andjoin # => "think, feel and enjoy"
puts %w[ mitchell webb ].andjoin # => "mitchell and webb"
puts %w[ yes ].andjoin # => "yes"

puts %w[ happy fun monkeypatch ].andjoin(', ', ', and ') # => "happy, fun, and monkeypatch"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...