7

I'm doing the following:

array_variable = collection.map do |param|
  some value with param
end
return array_variable.compact

Can I call map and compact in one statement somehow, so I can return the result instantly?

I'm thinking on something like this (it may be invalid, however):

array_variable = block_code param.compact 
# block_code here is a method for example which fills the array
Stefan
  • 109,145
  • 14
  • 143
  • 218
MattSom
  • 2,097
  • 5
  • 31
  • 53
  • Your question is unclear. You can only call methods on objects, but blocks aren't objects, so you can't call methods on them. You can reify a block into a `Proc` object, and *then* you can call methods on it; but `Proc`s don't have a `compact` method. (What does it even *mean* to "compact a block"?) – Jörg W Mittag Jun 08 '17 at 11:26
  • I'm surely not all clear with Ruby at the moment. I want to compact the array object, but I'm filling it inside the do block. I did not say what I was thinking is good, I only wanted to clarify that I want to fill and compact the array in once. Like a function composition. – MattSom Jun 08 '17 at 11:47
  • So, you are asking whether you can call a method on the return value of a method? – Jörg W Mittag Jun 08 '17 at 12:16
  • No. Stefan clarified the issue. – MattSom Jun 08 '17 at 12:25
  • 1
    Now I am even more confused. You accepted an answer as correct which shows you how to call a method (in this case `compact`) on the return value of another method (in this case `map`), but that is not what you are asking? Then, what *is* it you are asking and why did you accept an answer that answers a question you are not asking? – Jörg W Mittag Jun 08 '17 at 12:41
  • A method which uses a do..end block. Yes, in this context this is what I was asking for, my bad. – MattSom Jun 08 '17 at 17:34
  • 1
    I understood the question immediately and find it very useful. – WestCoastProjects Apr 03 '20 at 15:20

1 Answers1

16

yes, you can call a method here.

In your case,

array_variable = collection.map do |param|
  # some value with param
end.compact

OR

array_variable = collection.map{ |param| some value with param }.compact

As pointed out by @Stefan, assignment is not required, you can directly use return and if that's the last line of method you can omit return too..

Md. Farhan Memon
  • 6,055
  • 2
  • 11
  • 36
  • 1
    In your case, you are calling `compact` on the return value of `map` (which is an `Array`), while the question asks to "call method on a block". Now, I have no idea what "call method on a block" even means, but you are definitely calling `compact` on an `Array`. – Jörg W Mittag Jun 08 '17 at 11:30
  • 1
    yes ofcourse, it very much depends on the return type, since `map` returns an array and `compact` belongs to it it is good to go but not always..that's why I mentioned 'yes you can call a method here' – Md. Farhan Memon Jun 08 '17 at 11:33
  • @JörgWMittag I think you are slightly making an unnecessary quarrel, Md.FarhanMemon realized instantly what I want, surely you did as well. My question title was wrong, I admit. But yes, I want to compact the result of the block, as it clearly mapped the return values into the array. – MattSom Jun 08 '17 at 11:50
  • 2
    Note that the OP wants to return the result, so the assignment to `array_variable` is superfluous. Simply `return collection.map { ... }.compact` (you can even omit `return` if this is the method's last statement) – Stefan Jun 08 '17 at 11:52
  • I personally am annoyed by the `end.compact` syntax, because the letters kind of run together, so it's easy to miss on a quick scan. My view is that there's nothing wrong with a multi-line block delimited by curly braces. – Kelvin Jan 26 '18 at 19:22