Skip to content

Instantly share code, notes, and snippets.

@nonowarn
Created September 1, 2009 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nonowarn/179071 to your computer and use it in GitHub Desktop.
Save nonowarn/179071 to your computer and use it in GitHub Desktop.
Reified Object#send
class Send
class << self
def method_missing meth, *holes_or_args, &block
do_send = -> args {
-> receiver {
receiver.__send__(meth, *args, &block)
}
}
if holes_or_args.any? { |hoa| hoa == Hole }
-> *args_for_holes {
actual_args = holes_or_args.map { |hoa| hoa == Hole ? args_for_holes.shift : hoa }
do_send[actual_args]
}
else
do_send[holes_or_args]
end
end
end
end
# TYMOWTDI: `data Hole = Hole` translated to Ruby
class Hole; end
class Object
def receive
yield self
end
end
# This script should invoked by spec command
describe 'usage' do
example 'simple send/receive' do
twice_all = Send.map { |n| n * 2 }
[1,2,3].receive(&twice_all).should == [2,4,6]
end
end
describe 'holes' do
it 'is left for arguments' do
zero_pad = Send.rjust(Hole, '0')
"foo".receive(&zero_pad[10]).should == "foo".rjust(10, '0')
end
it 'should be filled different arguments each time' do
to_i = Send.to_i(Hole)
"10".receive(&to_i[10]).should == "10".to_i(10)
"10".receive(&to_i[16]).should == "10".to_i(16)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment