Skip to content

[Cookbook] MapToObject

Camilo edited this page Apr 16, 2021 · 1 revision

This is a small trick to convert a Map to an Object using the Meta module.

Was created by Michel Hermier in issue 912.

class MapToObject {
    static call(map) {
        __uniqueid = __uniqueid || 0
        __uniqueid = __uniqueid + 1
        
        var classname = "NewObjectFromMap_%(__uniqueid)"
        var keys = map.keys
    
        var   out = "var %(classname)_shadow = {}\n"
        out = out + "return Fn.new {|map|\n"

        // Copy the map in the shadow
        out = out + "\tfor (key in map.keys) %(classname)_shadow[key] = map[key]\n"
    
        out = out + "\tclass %(classname) {\n"
        out = out + keys.reduce("") {|str, key| str + "\t\tstatic %(key) { __%(key) != null ? __%(key) : __%(key) = %(classname)_shadow[\"%(key)\"] }\n" }
        out = out + "\t}\n"
        out = out + "\treturn %(classname)\n"
        out = out + "}"

        return Meta.compile(out).call().call(map)
    }
}

Example Usage

var obj = MapToObject.call({ "hello": "wren" })
var obj2 = MapToObject.call({"one" : 1})
var obj3 = MapToObject.call({"two" : 2})

System.print(obj.hello) // expect: wren
System.print(obj2.one) // expect: 1
System.print(obj3.two) // expect: 2