Login  Register

Re: Breaking changes with 0.1.4?

Posted by asotobu on Oct 08, 2013; 6:59pm
URL: https://discuss.asciidoctor.org/Breaking-changes-with-0-1-4-tp757p763.html

Hello, we can talk tomorrow about exactly the problem of serialization, but before that let me show you the code that deals with HashMap to RubyHash:

This method is called when you want to render something (in this case an string). The Map (the one you had send as argument) is received as argument and is converted to RubyHash by using RubyHashUtil.

public String render(String content, Map<String, Object> options) {

        this.rubyGemsPreloader.preloadRequiredLibraries(options);
        addRubyRuntimeAsAttribute(options);
        RubyHash rubyHash = RubyHashUtil.convertMapToRubyHashWithSymbols(
                rubyRuntime, options);

        Object object = this.asciidoctorModule.render(content, rubyHash);
        return returnExpectedValue(object);

}


Note that a new instance of hash is created, and then for each element, the key is converted to a Ruby symbol, and the value to a Ruby object calling toRubyObject.

 public static RubyHash convertMapToRubyHashWithSymbols(Ruby rubyRuntime,
            Map<String, Object> options) {

        RubyHash rubyHash = new RubyHash(rubyRuntime);

        Set<Entry<String, Object>> optionsSet = options.entrySet();

        for (Entry<String, Object> entry : optionsSet) {

            String key = entry.getKey();
            Object value = entry.getValue();

            RubySymbol newSymbol = RubyUtils.toSymbol(rubyRuntime, key);
            IRubyObject iRubyValue = toRubyObject(rubyRuntime, value);

            rubyHash.put(newSymbol, iRubyValue);

        }

        return rubyHash;

    }

 private static IRubyObject toRubyObject(Ruby rubyRuntime, Object value) {

        if (value instanceof List) {
            return toRubyArray(rubyRuntime, (List) value);
        } else {

            if(value instanceof String) {
                String stringValue = ((String)value);
               
                if(stringValue.startsWith(":")) {
                    return RubyUtils.toSymbol(rubyRuntime, stringValue.substring(1));                    
                }
            }
           
            IRubyObject iRubyObject = JavaEmbedUtils.javaToRuby(rubyRuntime,
                    value);
            return iRubyObject;
        }
    }

    private static IRubyObject toRubyArray(Ruby rubyRuntime, List values) {

        RubyArray rubyArray = RubyArray.newArray(rubyRuntime, values.size());

        for (Object value : values) {
            rubyArray.add(toRubyObject(rubyRuntime, value));
        }

        return rubyArray;
    }

Hope this clarifies a bit what AJI is doing internally, for what I understand, you need that AJI in high level it creates a copy of given options, right?