'Negate a predicate Proc in Ruby

I have a Proc, which is predicate.

Proc.new { |number| number.even? }

Is there a way to somehow create another Proc which have the opposite meaning? I can't change the "body" of the Proc, because the Proc will come as function parameter. So I want something like this:

not(Proc.new { |number| number.even? }
# which of course doesn't work :(

and I want it to do the same as

Proc.new { |number| number.odd? }

The idea is that I want a function similar to this:

def negate(proc)
  negated proc with meaning opposite of this of proc
end

Thank you very much in advance!



Solution 1:[1]

The following method returns the procedure opposite to the provided one.

def negate(procedure)
  Proc.new { |*args| !procedure.call(*args) }
end

or, using shorter notation:

def negate(procedure)
  proc { |*args| !procedure.call(*args) }
end

Solution 2:[2]

Does this help at all?

p = Proc.new { |number| number.even? }
p.call(1) #=> false
!p.call(1) #=> true

Solution 3:[3]

For a more functional-programming-like (albeit possibly more cryptic) approach, you can utilise two Ruby facts:

is_odd = proc { |n| n % 2 == 1 }
is_even = is_odd >> :!.to_proc

p is_even.call(3) # => false

# Or, extracting into a utility
negate = :!.to_proc
is_even = negate << is_odd # or is_odd >> negate

p is_even.call(3) # => false

Voila! Maybe not the most obvious, but a bit of fun.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Bala
Solution 3 shalvah