'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 a regular method defined on Ruby objects- you can compose procs in Ruby with
>>and<<
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 |
