Skip to content

Instantly share code, notes, and snippets.

@rubysolo
Forked from avdi/message.rb
Created July 1, 2013 01:32
Show Gist options
  • Save rubysolo/5897821 to your computer and use it in GitHub Desktop.
Save rubysolo/5897821 to your computer and use it in GitHub Desktop.
# An experiment in higher-order (?) messages in Ruby.
class Message
attr_reader :name
attr_reader :arguments
def initialize(name, *arguments)
@name = name
@arguments = arguments
end
def name=(name)
@name = name.to_sym
end
def arguments=(arguments)
@arguments = Array(arguments)
end
def bind(receiver)
->(&block) {
receiver.public_send(name, *arguments, &block)
}
end
def call(receiver, &block)
bind(receiver).call(&block)
end
def to_s
"##{name}(#{arguments.inspect})"
end
def to_ary
[name, *arguments]
end
alias to_a to_ary
def to_proc
->(receiver, &block){
bind(receiver).call(&block)
}
end
end
class Symbol
def call(*arguments)
Message.new(self, *arguments)
end
end
replace_x_with_o = :tr.('x', 'o')
# => #tr(["x", "o"])
splatted = *replace_x_with_o
# => [:tr, "x", "o"]
str = "fxx"
str.public_send(*replace_x_with_o) # => "foo"
message_send = replace_x_with_o.bind(str)
# => #<Proc:0x00000000e2fc70@-:19 (lambda)>
message_send.call # => "foo"
replace_x_with_o.call("fxx")
# => "foo"
strings = %w[lxxk bxxk nxxk].map(&:tr.('x', 'o'))
# => ["look", "book", "nook"]
# I also wonder about saving the block as well as the arguments inside
# a Message. Good idea? Bad idea?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment