Help save net neutrality! Learn more.
Close

OneArgFunction hyperbolic sample bugged

Help
Feriaman
2012-11-15
2013-05-14
  • Feriaman

    Feriaman - 2012-11-15

    Hello,

    I finally figured out some workaround to make the "hyperbolic" sample work. But it's pretty ugly.
    Maybe I'm just stupid, or maybe the Javadoc is outdated ?

    First issue :
    Here is the Javadoc lua code

    local t = require('hyperbolic')
    

    I had to figure out that the real code was something like

    local t = require('com.feriaman.myluajtestproject.hyperbolic')
    

    Second issue :
    Here is the Javadoc Java code

     public class hyperbolic extends org.luaj.vm2.lib.OneArgFunction {
        public hyperbolic() {}
        public LuaValue call(LuaValue arg) {
            switch ( opcode ) {
            case 0: {
                LuaValue t = tableOf();
                this.bind(t, hyperbolic.class, new String[] { "sinh", "cosh" }, 1 );
                env.set("hyperbolic", t);
                return t;
            }
            case 1: return valueOf(Math.sinh(arg.todouble()));
            case 2: return valueOf(Math.cosh(arg.todouble()));
            default: return error("bad opcode: "+opcode);
            }
        }
     }
    

    But the "env" field doesn't exists, maybe it was replaced by something, but i didn't figured out what. So I Had to add my own static field named "env" and initialised it manually.

    It is static because, as it is not automatically initialized, it would be null most of the times.

    Here is the HUGLY code:

    public class hyperbolic extends org.luaj.vm2.lib.OneArgFunction {
        public static LuaValue env;
        public hyperbolic() {}
        public LuaValue call(LuaValue arg) {
            switch ( opcode ) {
            case 0: {
                LuaValue t = tableOf();
                this.bind(t, hyperbolic.class, new String[] { "sinh", "cosh" }, 1 );
                env.set("hyperbolic", t);
                return t;
            }
            case 1: return valueOf(Math.sinh(arg.todouble()));
            case 2: return valueOf(Math.cosh(arg.todouble()));
            default: return error("bad opcode: "+opcode);
            }
        }
    }
    
    Globals globals = JsePlatform.debugGlobals();
    hyperbolic toto = new hyperbolic();
    toto.env = globals;
    globals.load(toto);
    
     
  • Feriaman

    Feriaman - 2012-11-15

    I should add that I unsuccessfully tried to use things like :

    get(ENV).set("hyperbolic", t);
    
    get("_ENV").set("hyperbolic", t);
    
    get("_G").set("hyperbolic", t);
    
    _G.set("hyperbolic", t);
    
     
  • James Roseborough

    I’ve just released versions 2.0.3 and 3.0-alpha2 which may address these issues.

    If you are using v 2.0.2/2.0.3 (supported) the updated javadoc is here:
    http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/LibFunction.html link

    If you are using v 3.0-alpha1/3.0-alpha2 (not yet supported) the updated API is here:
      http://luaj.sourceforge.net/api/3.0/org/luaj/vm2/lib/LibFunction.html  link
     
    The main difference between 2.0 and 3.0 is the major change in the way globals and environments are handled to mimic the changes between lua 5.1 and lua 5.2.

    Your post revealed a defect in the alpha1 release, because there was no way to get the environment from Java code loaded via require().  I’ve changed the alpha2 release to provide
    the argument as the “extra” argument when the Java searcher is found.

    Also, instead of using op-codes, I think it is simpler to just create a new class for each LuaFunction.  This makes the code more readable, and in any case Java should be good at loading many classes by now.   Also, this will execute faster since there is not an extra call and switch statement per invoation.

    Here is the new recommendation for version 3.0-alpha2:

    import org.luaj.vm2.LuaValue;
    import org.luaj.vm2.lib.*;
    
     public class hyperbolic extends TwoArgFunction {
        public hyperbolic() {}
        public LuaValue call(LuaValue modname, LuaValue env) {
            LuaValue library = tableOf();
            library.set( "sinh", new sinh() );
            library.set( "cosh", new cosh() );
            env.set( "hyperbolic", library );
            return library;
        }
        static class sinh extends OneArgFunction {
            public LuaValue call(LuaValue x) {
                return LuaValue.valueOf(Math.sinh(x.checkdouble()));
            }
        }
    
        static class cosh extends OneArgFunction {
            public LuaValue call(LuaValue x) {
                return LuaValue.valueOf(Math.cosh(x.checkdouble()));
            }
        }
    }
    

    If you don’t like all the classes, and still want to use opcodes, then beware that I will remove the default opcode support before I release 3.0, so you will have to switch to creating and managing yourself. 

    I've also enhanced the documentation around this in the README for 3.0
      http://www.luaj.org/luaj/README.html#5 link

     

Log in to post a comment.