lib/culerity/remote_object_proxy.rb in caius-culerity-0.1.7 vs lib/culerity/remote_object_proxy.rb in caius-culerity-0.1.8

- old
+ new

@@ -1,7 +1,7 @@ module Culerity - + class CulerityException < StandardError def initialize(message, backtrace) super message #self.backtrace = backtrace end @@ -10,46 +10,66 @@ class RemoteObjectProxy def initialize(remote_object_id, io) @remote_object_id = remote_object_id @io = io end - + # # Commonly used to get the HTML id attribute # Use `object_id` to get the local objects' id. # def id send_remote(:id) end - + def method_missing(name, *args) send_remote(name, *args) end - + # # Calls the passed method on the remote object with any arguments specified. # Behaves the same as <code>Object#send</code>. # - def send_remote(name, *args) - @io << "[#{remote_object_id}, \"#{name}\", #{args.map{|a| a.inspect}.join(', ')}]\n" + # If you pass it a block then it will append the block as a "lambda { … }". + # If your block returns a lambda string ("lambda { … }") then it will be passed + # straight through, otherwise it will be wrapped in a lambda string before sending. + # + def send_remote(name, *args, &blk) + input = [remote_object_id, %Q{"#{name}"}, *args.map{|a| a.inspect}] + input << block_to_string(&blk) if block_given? + @io << "[#{input.join(", ")}]\n" process_result @io.gets.to_s.strip end - + def exit @io << '["_exit_"]' end - + private - + def process_result(result) res = eval result if res.first == :return res[1] elsif res.first == :exception raise CulerityException.new("#{res[1]}: #{res[2]}", res[3]) end end - + + # + # Takes a block and either returns the result (if it returns "lambda { … }") + # or builds the lambda string with the result of the block in it. + # + # Returns a string in the format "lambda { … }" + # + def block_to_string &block + result = block.call.to_s + unless result.is_a?(String) && result[/^lambda \s* \{ .*? \}/x] + result = "lambda { #{result} }" + end + result + end + def remote_object_id @remote_object_id end end end \ No newline at end of file