WeBWorK Main Forum

Possible to use Inline module to include code in other languages?

Possible to use Inline module to include code in other languages?

by Andrew Dabrowski -
Number of replies: 5
I'm trying to get a minimal example of the use of Inline::Lua to work. I've written a small PGLua.pm module, added it and Inline::Lua to the list of safe modules, and tried two different ways of calling Lua code. Neither works.
package PGLua;

use Inline 'Lua' => <<LUA
function lplus( x, y )
return x + y
end
LUA

sub luaPlus{
my $self = shift;
my ( $x, $y ) = @_;
return lplus( $x, $y );
}

1;
The above PGLua.pm produces the following error in the Apache log.

[Sat Aug 22 13:06:34.570020 2015] [perl:warn] [pid 31950] [client 127.0.0.1:44738] [/webwork2/NewGenEd/Undefined_Set/1/] Failed to evaluate module PGLua: syntax error at /home/dabrowsa/webwork/pg/lib/PGLua.pm line 11, near "sub luaPlus"\nsyntax error at /home/dabrowsa/webwork/pg/lib/PGLua.pm line 15, near "}"\nCompilation failed in require at (eval 882) line 1., referer: http://127.0.0.1/webwork2/NewGenEd/instructor/setmaker/
Whereas the following produces no error in the Apache log, but apparently the Lua code at the bottom remained unread because when I try to use PGLua::luaPlus in the context of a webwork problem it produces the WW error "##Undefined subroutine &PGLua::lplus called at [PG]/lib/PGLua.pm line 10." (Full error message below.)
package PGLua;

use Inline 'Lua';

sub luaPlus{
my $self = shift;
my ( $x, $y ) = @_;
return lplus( $x, $y );
}

1;

__END__
__Lua__

function lplus( x, y )
return x + y
end

Warning messages

  • ERROR in old_safe_ev, PGbasicmacros.pl: <PRE>
  • ## There is an error occuring inside evaluation brackets \{ ...code... \}
  • ## somewhere in an EV2 or EV3 or BEGIN_TEXT block.
  • ## Code evaluated:
  • ## Data::Dumper::Dumper
  • PGLua::luaPlus( 2, 3 )
  •  
  • ##Undefined subroutine &PGLua::lplus called at [PG]/lib/PGLua.pm line 10.
  • ##</PRE><BR/>
  • at line 1671 of [PG]/macros/PGbasicmacros.pl

Should I give this up as hopeless, or are there more things to try?
In reply to Andrew Dabrowski

Re: Possible to use Inline module to include code in other languages?

by Michael Gage -
I think you need a ; after the first line

use Inline 'Lua' => <<LUA;
...

LUA

is the syntax for  a "here" document.

There might be other problems with Safe -- I didn't check it.  It's worth checking to see if this runs as a standalone script. (Fewer variables to cause trouble -- and much quicker to debug. )


The second version doesn't run because nothing is compiled after an __END__ statement.

-- Mike

In reply to Michael Gage

Re: Possible to use Inline module to include code in other languages?

by Davide Cervone -
Apparently, putting the Lua code after __END__ is on of the ways that Lua works (see the documentation).

I suspect the actual issue is that the lua code is in the main package rather than that PGLua package, and the use of lplus within the package PGLua would be looking for PGLua::lplus (as indicated in the error message).

One thing to try would be

package PGLua;

use Inline 'Lua';

sub luaPlus{
  my $self = shift;
  my ( $x, $y ) = @_;
  return main::lplus( $x, $y );
}
and see if that works. It might also be possible to use
__Lua__

function PGLua::lplus( x, y )
  return x + y
end
though I think that is less likely to work.
In reply to Davide Cervone

Re: Possible to use Inline module to include code in other languages?

by Andrew Dabrowski -
Thanks! I can't believe I forgot a semicolon (no, I can believe it).

This works:

package PGLua;

use Inline (Config => DIRECTORY => "/tmp/");
use Inline Lua => <<LUA;
function lplus( x, y )
return x + y
end
LUA

sub luaPlus{
my ( $x, $y ) = @_;
return lplus( $x, $y );
}

1;
The __Lua__ syntax at the end of the file is supposed to work, but maybe WW is truncating the reading?

In reply to Andrew Dabrowski

Re: Possible to use Inline module to include code in other languages?

by Andrew Dabrowski -
I'd like to use PGLua.pm to define utilities for reading Lua code, which would then be placed in macro files to be loaded as needed. But apparently the webwork safe environment has a problem with Inline->bind, because the following code produces a "require trapped" error.
package PGLua;

use Inline;
use Inline (Config => DIRECTORY => "/tmp/");

sub readLua{
my $def = shift;
my $funstr = "function luaFunction $def";
Inline->bind( Lua => $funstr );
return &luaFunction(2,3);
}

1;
Here's the error.

  • ERROR in old_safe_ev, PGbasicmacros.pl: <PRE>
  • ## There is an error occuring inside evaluation brackets \{ ...code... \}
  • ## somewhere in an EV2 or EV3 or BEGIN_TEXT block.
  • ## Code evaluated:
  • ## Data::Dumper::Dumper
  • PGLua::readLua( "(x,y) return x + y end" )
  •  
  • ##'require' trapped by operation mask at /usr/lib/perl5/core_perl/Digest/MD5.pm line 3.
  • Compilation failed in require at /usr/share/perl5/site_perl/Inline.pm line 461.
  • ##</PRE><BR/>
  • at line 1671 of [PG]/macros/PGbasicmacros.pl

Btw, there is no require at line 3 in MD5.pm, although the line reference 461 in Inline is exact. I tried pushing all modules mentioned in require statments in MD5.pm onto ${pg}{modules}, but nothing changed.
In reply to Andrew Dabrowski

Re: Possible to use Inline module to include code in other languages?

by Andrew Dabrowski -
If Inline->bind can't be used, then all Lua code must go in .pm files. Should that be a deal-breaker?