Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
# # Stupid bit of ruby muckin # # Was trying to do something like this: # # "svn co #{src} #{dest}".to(:puts).to(:system) # # It's pretty hard if you want the method calls in the #to to be passed to the # receiver where the line resides. It would be easy if we had a proper #caller # or Binding.of_caller # # But we don't (yet), so I thought I could achieve the same effect by keeping # a hold of the receiver in a proxy object. So, it goes like this: # # pass("svn co #{src} #{dest}").to(:puts).to(:system) # # I added a few niceties to make the return value sensible, and also added #into # which modifies the passed object in place # # pass("Foo").into("bar.+").to(:puts) # # I have no idea if this is useful, if you find yourself passing the same argument into # some methods over and over, then you could use this. # # Feb 2008 - Ian White http://blog.ardes.com/ian # # p.s. I was trying to get a nice sugary syntax rush, # there's already a bunch of constructs for doing this. # # Compare: # # # plain ruby # msg = "oooh!" # MyObj.foo msg # MyObj.far msg # MyObj.faz msg # # # #returning from ActiveSupport # returning "oooh!" do |s| # MyObj.foo s # MyObj.far s # MyObj.faz s # end # # # #pass (this code) # MyObj.pass("oooh!").to :foo, :far, :faz # require 'rubygems' require 'active_support' # # Usage: # # Object#pass(obj) creates a PassProxy which delegates methods to obj # # except # #to: which sends obj to the specified methods, returning the PassProxy # #into: which sends obj to the specified methods, updating the PassProxy with the results # # The receiver of #pass is used to determine where the methods are sent in #to and #into # # pass("str").to :puts, :system # # calls main.puts("str") # # calls main.system("str") # # => "str" # # my_obj.pass(1).into(:times_2) # # calls my_obj.times_2(1) # # => 2 # # Can be chained # # pass(1).into("2.+").to(:puts) # # 2.+(1) # # => 3 # # main.puts(3) # # => 3 class Object def pass(*object, &block) PassProxy.new(self, *object, &block) end end class PassProxy < BasicObject def initialize(context, *object, &block) object = object.first if object.size == 1 @__context__, @__object__, @__block__ = context, object, block end def method_missing(method, *args, &block) @__object__.send(method, *args, &block) end def respond_to?(method) @__object__.respond_to?(method) end def to(*methods, &block) methods << block if block_given? methods.each {|method| __call_method__(method)} self end def into(*methods, &block) methods << block if block_given? methods.each {|method| @__object__ = __call_method__(method)} self end private def __call_method__(method) if method.is_a?(Symbol) @__context__.send method, *@__object__, &@__block__ elsif method.respond_to?(:call) @__context__.instance_exec *@__object__, &method elsif method.is_a?(String) @__context__.instance_exec *@__object__, &eval("proc{|*a| #{method}(*a)}") else raise "I can't figure out how to call #{method.inspect}" end end end
This paste will be private.
From the Design Piracy series on my blog: