2

In the following code:

def main
  someArray.all? { |item| checkSomething(item) }
end

private
  def checkSomething(arg)
    ...
  end

How do I shorten the all? statement in order to ged rid of the redundant item variable?

I'm looking for something like someArray.all?(checkSomething) which gives a "wrong number of arguments" error.

9
  • Where is the item variable? Commented Jul 6, 2015 at 11:27
  • The OP, you can't do that with #all? .. as it doesn't take any parameter as argument.. You have to go with block .. Commented Jul 6, 2015 at 11:30
  • You are actually calling checkSomething without any argument in someArray.all?(checkSomething), that's why it complains. Commented Jul 6, 2015 at 11:31
  • Nope, there's no shorter way. The to_proc shortcut (for example, ary.map(&:to_s) ) does not apply here. Commented Jul 6, 2015 at 11:34
  • @limekin I know.. Block is a special argument.. Commented Jul 6, 2015 at 11:34

6 Answers 6

3

You could have a slightly shorter code if checkSomething was a method on your object class. Don't know what it is, so, I'm guessing, you're working with primitives (numbers, strings, etc.). So something like this should work:

class Object
  def check_something
    # check self
  end
end

some_array.all?(&:check_something)

But this is, of course, a horrible, horrible way of going about it. Saving a few keystrokes at the cost of such global pollution - absolutely not worth it. Moreover, even this trick will not be available as soon as you will need to pass additional parameters to the check method.

Besides, the original code is quite readable too.

Sign up to request clarification or add additional context in comments.

Comments

3

You could use Object#method and Method#to_proc (i.e. &method) to get rid of the item variable, although it is slower:

def main(array)
  array.all?(&method(:check_something))
end

def check_something(arg)
  arg.odd?
end

main [1,3,5] #=> true
main [1,3,6] #=> false

3 Comments

It's not any shorter, is it? :)
@SergioTulentsev It uses less variables ;-)
Yeah, but IIRC, using method is a non-negligible performance hit. It's up for the OP to decide what's more important :)
1

If checkSomething is an item method (i.e. defined in the class of the 'i' object) you could do symbol to proc...

def main
  someArray.all?(&:checkSomething)
end

A method only has access to passed arguments, or to selfso to bypass passing arguments you need to make the method an instance method of the object class (so it can use self)

The way you have it... where checkSomething is external to the i class... you can't do that.

Comments

0

Considering you want to keep your object's checkSomething private, I think this would be a good work around :

class Something
  def main
    someArray.all?(&checkSomething) 
  end

  private
    def checkSomething
      ->(item) do 
        # Checking part.
      end
    end
end

Comments

0

For block that executes a method with arguments, Checkout this way...

def main
  someArray.all? &checkSomething(arg1, arg2, ...)
end

private
def checkSomething(arg1, arg2, ...)
  Proc.new { |item| ..... }
end

Comments

-2

could you not use a Ruby's collection method 'any?' instead?

def main
  #students is an array of students
  students.any?(&:passed)
end

class Student
  def passed
    #code to check if student passed
  end
end

Ref http://ruby-doc.org/core-2.2.2/Enumerable.html#method-i-any-3F

2 Comments

all? and any? have the same constraint here... if you're using symbol-to-proc the method has to be a Student object method (as you did). Your answer would work with all? as well as any? so from that perspective there's no difference.
i did a little research on the difference between all? and any? there is a subtle difference...so yes depending on you requirement I agree you could use either

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.