Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can you define a block inline with ruby?

Tags:

ruby

Is it possible to define a block in an inline statement with ruby? Something like this:

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

Instead of this:

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

If you said tasks.collect(&:title).slice(0, this.length-1) how can you make 'this' refer to the full array that was passed to slice()?

Basically I'm just looking for a way to pass the object returned from one statement into another one, not necessarily iterating over it.

like image 475
bwizzy Avatar asked Aug 23 '26 12:08

bwizzy


2 Answers

You're kind of confusing passing a return value to a method/function and calling a method on the returned value. The way to do what you described is this:

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

If you want to do it the way you were attempting, the closest match is instance_eval, which lets you run a block within the context of an object. So that would be:

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

However, I would not do either of those, as it's longer and less readable than the alternative.

like image 60
Chuck Avatar answered Aug 26 '26 01:08

Chuck


I'm not sure exactly what you're trying to do, but:

If you said tasks.collect(&:title).slice(0, this.length-1) how can you make 'this' refer to the full array that was passed to slice()?

Use a negative number:

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

Also, in:

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

you've got something weird going on with your quotes, I think.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!