Skip to content

Instantly share code, notes, and snippets.

@mudge
Last active August 29, 2015 14:16
Show Gist options
  • Save mudge/592689ad1a24050154ad to your computer and use it in GitHub Desktop.
Save mudge/592689ad1a24050154ad to your computer and use it in GitHub Desktop.
More noodling with #to_proc but, this time, through #===, c.f. http://mudge.name/2014/11/26/data-structures-as-functions.html
require 'set'
# Let's provide a default to_proc in terms of threequals
class Object
def to_proc
method(:===).to_proc
end
end
class Set
def ===(element)
element if member?(element)
end
end
class Hash
alias_method :===, :[]
end
class Array
alias_method :===, :[]
end
[:name, :age].map(&{name: 'Bob', age: 42})
#=> ["Bob", 42]
[0, 2].map(&%w(foo bar baz quux))
#=> ["foo", "baz"]
%w(Alice Bob Crispin).reject(&Set['Bob', 'Daisy'])
#=> ["Alice", "Crispin"]
case "Alice"
when Set["Alice", "Bob"]
"Welcome!"
end
#=> "Welcome!"
# As Proc#=== is already defined to call the proc, we could try the other way around:
require 'forwardable'
require 'set'
class Object
extend Forwardable
def_delegator :to_proc, :===
# We have to provide a default implementation that matches the behaviour of
# Kernel#=== to prevent a nasty TypeError
def to_proc
proc { |other| self.equal?(other) || self == other }
end
end
class Hash
def to_proc
method(:[]).to_proc
end
end
class Array
def to_proc
method(:[]).to_proc
end
end
class Set
def to_proc
proc { |element| element if member?(element) }
end
end
[:name, :age].map(&{name: 'Bob', age: 42})
#=> ["Bob", 42]
[0, 2].map(&%w(foo bar baz quux))
#=> ["foo", "baz"]
%w(Alice Bob Crispin).reject(&Set['Bob', 'Daisy'])
#=> ["Alice", "Crispin"]
case "Alice"
when Set["Alice", "Bob"]
"Welcome!"
end
#=> "Welcome!"
Set["Alice", "Bob"] === "Bob"
#=> "Bob"
Set["Alice", "Bob"] === "Carol"
#=> nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment