# -*- coding: utf-8 -*- ########################################################################################## # @author Rodrigo Botafogo # # Copyright © 2016 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify, # and distribute this software and its documentation, without fee and without a signed # licensing agreement, is hereby granted, provided that the above copyright notice, this # paragraph and the following two paragraphs appear in all copies, modifications, and # distributions. # # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, # OR MODIFICATIONS. ########################################################################################## class Renjin class Callback include Java::RbScicom.RubyCallbackInterface include Renjin::RBSexp attr_reader :ruby_obj #---------------------------------------------------------------------------------------- # #---------------------------------------------------------------------------------------- def initialize(ruby_obj) @ruby_obj = ruby_obj end #---------------------------------------------------------------------------------------- # #---------------------------------------------------------------------------------------- def run(method, *args) # puts "method #{method} called with args: #{args}" # The returned value from the called method should be packed. Callback.pack(@ruby_obj.send(method, *args)) end #---------------------------------------------------------------------------------------- # #---------------------------------------------------------------------------------------- def get_class(class_name) run("const_get", class_name) end #---------------------------------------------------------------------------------------- # #---------------------------------------------------------------------------------------- def build(class_name, *args) klass = get_class(class_name) klass.run("new", *args) end #---------------------------------------------------------------------------------------- # Scope can be: # * external: only the received object is packed # * internal: only the internal objects are packed. In this case, the received object # must respond to the 'each'. # * all: packs both internal and external #---------------------------------------------------------------------------------------- def self.pack(obj, scope: :external) # Do not pack basic types Boolean, Numberic or String case obj when TrueClass, FalseClass, Numeric, String return obj end case scope when :internal raise "Cannot rpack object's internals as it does not respond to the :each method." if !obj.respond_to?(:each) obj.map { |pk| Callback.new(pk) } when :external Callback.new(obj) when :all Callback.new(obj.map! { |pk| Callback.new(pk) }) else raise "Scope must be :internal, :external or :all. Unknown #{scope} scope" end end end end =begin class Hash def deep_traverse(&block) stack = self.map{ |k,v| [ [k], v ] } while not stack.empty? key, value = stack.pop yield(key, value) if value.is_a? Hash value.each{ |k,v| stack.push [ key.dup << k, v ] } end end end end =end