返回 Ruby 中对象的产量的方法

发布于 2024-12-07 09:29:46 字数 467 浏览 3 评论 0原文

Ruby 中是否有一种方法可以返回传递给对象的块的内容?

例如,如果我想将一个对象放入数组中怎么办?

在理想的世界中,我们会做(我正在寻找的):

"string".reverse.upcase.something{ |s| send(s) }

它将返回一个带有我的对象的数组,相当于:

send("string".reverse.upcase)

如果我有我的对象开始,并且在更复杂的情况下可能会变得混乱,那么它是不可链接的场景。

因此 something 方法将返回块的评估,例如 Array#map,但仅适用于一个元素。

Is there a method in Ruby that returns the content of the block passed on to an object?

For example, what if I have an object which I want to put in an array?

In an ideal world, we would do (what I'm looking for):

"string".reverse.upcase.something{ |s| send(s) }

which would return an array with my object, as equivalent to:

send("string".reverse.upcase)

which isn't chainable if I have my object to start with and can get messy in more complex scenarios.

So the something method would return the evaluation of the block, like Array#map, but for one element only.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

遗失的美好 2024-12-14 09:29:46

我不知道有这样的内置功能,但你可以轻松地自己完成

class Object
  def something(&block)
    block.call(self)
  end
end

p "foo".something { | o | [o] }
p 23.something { | x | p x; 42 }

["foo"]      # object "foo" put into an array
23           # object handed to block
42           # something return block's result

I don't know of such a thing built-in but you can easily do it yourself:

class Object
  def something(&block)
    block.call(self)
  end
end

p "foo".something { | o | [o] }
p 23.something { | x | p x; 42 }

gives

["foo"]      # object "foo" put into an array
23           # object handed to block
42           # something return block's result
白首有我共你 2024-12-14 09:29:46

在最初的问题提出六年后,Ruby 2.5.0 引入了 Object#yield_self,然后在 Ruby 2.6 中缩短为 #then

 类对象
   def Yield_self(*args)
     产量(自身,*args)
   结尾
 结尾

[...]

它执行块并返回其输出。

(Ruby 功能 #6721)

例如:

2.then{ |x| x*x }  # => 4

Six years after the original question, Ruby 2.5.0 introduced Object#yield_self, then shortened in Ruby 2.6 as #then:

 class Object
   def yield_self(*args)
     yield(self, *args)
   end
 end

[...]

It executes the block and returns its output.

(Ruby Feature #6721)

For example:

2.then{ |x| x*x }  # => 4
忘年祭陌 2024-12-14 09:29:46

您是否在寻找 Object.tap

Are you looking for Object.tap ?

遥远的她 2024-12-14 09:29:46

我有时希望标准库中有类似的功能。例如,名称可以是 withwith_it

(使用新名称重复先前的代码)

class Object
  def with_it(&block)
    block.call(self)
  end
end

用法示例:

x = [1, 2, 3, 4, 5].map {|x| x * x }.with_it do |list|
   head = list.unshift
   list << head * 10
   list.join " / "
end

与以下内容相反:

list = [1, 2, 3, 4, 5].map {|x| x * x }
head = list.unshift
list << head * 10
x = list.join " / "

虽然后者更容易理解,但前者具有在我看来,保持变量 listhead 范围以及对 x 的赋值的好处更加清晰(对 x< /code> 必须插入到代码的最后一行)。如果代码是更大方法的一部分,那么范围界定将是一个好处。

因此,使用 with_it 的另一个选择是将代码放在单独的方法中。例如:

def mult_head_and_join(list)
    head = list.unshift
    list << head * 10
    list.join " / "
end

x = mult_head_and_join [1, 2, 3, 4, 5].map {|x| x * x }

不知道在这里结束什么,但我想我会投票支持 with_it 包含在标准库中

I sometimes wish for a similar function in the standard library. The name could for example be with or with_it

(Repeating previous code with new name)

class Object
  def with_it(&block)
    block.call(self)
  end
end

Example usage:

x = [1, 2, 3, 4, 5].map {|x| x * x }.with_it do |list|
   head = list.unshift
   list << head * 10
   list.join " / "
end

As opposed to:

list = [1, 2, 3, 4, 5].map {|x| x * x }
head = list.unshift
list << head * 10
x = list.join " / "

While the latter is easier to understand, the former has the benefit of keeping the variables list and head scoped and the assignment to x is more clear in my opinion (the assignment to x has to be inserted into the last line of the code). Scoping would be a benfit if the code was a part of a larger method.

Another option to using with_it would thus be putting the code in a separate method. Eg:

def mult_head_and_join(list)
    head = list.unshift
    list << head * 10
    list.join " / "
end

x = mult_head_and_join [1, 2, 3, 4, 5].map {|x| x * x }

Not sure what to conclude with here, but I guess I'd vote for with_it to be included in the standard library

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文