Home > Net >  Wrapping array method for cleaner more dry code
Wrapping array method for cleaner more dry code

Time:12-31

I'm trying to clean up my code and figure out a way to pass the array method .all?. Here is the code:

if <condition>
  parent_1.children.all? {|c| <condition>} ? result_of_true : result_of_false
else
  parent_2.children.all? {|c| <condition>} ? result_of_true : result_of_false
end

They are both using .all? {|c| <condition>}. I'm trying to get it so I can shorten this line up and though maybe I could do something like create a scope on each of the children and use that, maybe create a proc and use that?

I've tried the following:

def new_all?
  proc { |*args| args.all? {|c| c.attribute} }
end

if <condition>
  parent_1.child.new_all? ? result_of_true : result_of_false
else
  parent_2.child.new_all? ? result_of_true : result_of_false
end

# return example: [false, false, true]

or maybe something on the child class like:

def self.new_all?
  all? {|c| <condition>}
end

There has to be a way to do this. I'm hoping something outside of having to work with the actual Array class.

This seems to return an array of the results but obviously not a single boolean value that you would expect from all?.

CodePudding user response:

Why not just define a simple method and then use a one line ternary?

def new_all? (x)
 x.all? {|item| <condition>} ? <result of true> : <result of false>
end

<other_condition> ? new_all?(a) : new_all?(b)

CodePudding user response:

A simple way of simplifying (hah!) the code would be to extract the duplicate code from the branches of the conditional expression and move it outside of the conditional expression:

if <condition>
  parent_1
else
  parent_2
end.child.all? {|c| <condition>} ? result_of_true : result_of_false

By the way, I find the mix of conditional expression and conditional operator hard to read. In fact, I find the conditional operator hard to read in general. It is also completely unnecessary in Ruby. The conditional operator is required in C, because it is an operator and thus an expression whereas the conditional statement is, well, a statement. But in Ruby, the conditional expression is already an expression, so there is no need for the conditional operator.

So, I would probably write it more like this:

if if condition
     parent_1
   else
     parent_2
   end.child.all? { |c| condition }
  result_of_true
else
  result_of_false
end

or maybe

if if condition then parent_1 else parent_2 end.child.all? { |c| condition }
  result_of_true
else
  result_of_false
end

However, this screams for extracting some of the stuff into methods or at least variables.

  • Related