Метод, который применяет себя к процессу - PullRequest
0 голосов
/ 07 марта 2012

Я хочу иметь метод, определенный в Object, который принимает блок и применяет приемник к блоку. Реализация будет выглядеть следующим образом:

class Object
    def apply ≺ pr.call(self) end
end

2.apply{|x| x * 3} # => 6

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

Мне часто случается так, что у меня есть метод, который принимает необязательный блок, и когда нет блока, я хочу вернуть некоторую return_value, вычисленную в методе, но когда есть блок, я хочу вернуть возвращаемое значение return_value, примененное к блоку. На данный момент у меня есть куча строк, таких как:

def method ..., &pr
  ...
  pr ? pr.call(return_value) : return_value
end

но я хочу последовательно написать

def method ..., &pr
  ...
  pr ? return_value.apply(&pr) : return_value
end

или даже лучше, со слегка измененным определением apply,

def method ..., &pr
  ...
  return_value.apply(&pr)
end

Ответы [ 3 ]

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

Я думаю, Object.tap - это то, что вы ищете:

"Abc".tap do |str|
  puts str
end
1 голос
/ 07 марта 2012

Разве это не идентично def apply; yield self; end?- steenslag

@ steenslag Да.Это.Я хочу получить этот эффект с self в качестве приемника.- sawa

Это то, что вы имеете в виду?

2.instance_eval { * 3 }
# => 6

К сожалению, это не работает.instance_eval просто запускает код, как если бы получатель был self.Операторы не предполагают self в качестве получателя, поэтому вам действительно нужно написать это:

2.instance_eval { self * 3 }
# => 6

Однако, в качестве подтверждения концепции, это возможно:

Numeric.send(:define_method, :plus) { |x| self + x }
2.instance_eval { plus 3 }
# => 5
0 голосов
/ 07 марта 2012

(после прочтения правки OP) AFAIK канонический способ написать это:

def purpose(*args)  #no &bl or &pr
  res = 42 #huge calculation
  return res unless block_given?
  yield res
end

p purpose(1,2)
purpose{|n| puts "from the block: #{n}"}
...