Campher: Perl embedded in Go

2,178 views
Skip to first unread message

Brad Fitzpatrick

unread,
May 7, 2011, 5:34:03 PM5/7/11
to golang-nuts
New Go package for embedding Perl in Go:


Example passing a Go closure to a Perl closure, running it and getting the results: 

package main
import (
"fmt"
)

func main() {
p := perl.NewInterpreter()
foo := p.Eval(`sub {
 my ($op, $v1, $v2) = @_;
 return "Perl says: " . $op->($v1, $v2);
};`)
concat := func(a, b string) string { return a + b }
fmt.Println("concat:", foo.CV().Call(concat, "foo", "bar"))

base := 0
add := func(a, b int) int {
base++;
return a + b + base
}
fmt.Println("add:", foo.CV().Call(add, 1, "40"))
fmt.Println("add:", foo.CV().Call(add, 1, "40"))
}

Outputs:

concat: Perl says: foobar
add: Perl says: 42
add: Perl says: 43


I presented this at a Perl conference, as part of a "Go for Perl Hackers" talk, but consider it more of a novelty or proof-of-concept.  I wouldn't run it in production yet.  :) 

- Brad
campher.png

Ondekoza

unread,
May 7, 2011, 8:26:55 PM5/7/11
to golang-nuts
This is really cool! Is the perl interpreter embedded into the binary
or do you call an external one?

Regards
Stefan Schroeder

Brad Fitzpatrick

unread,
May 7, 2011, 11:16:56 PM5/7/11
to Ondekoza, golang-nuts
Embedded in the same process.

Rich

unread,
May 8, 2011, 8:03:34 AM5/8/11
to golan...@googlegroups.com, Ondekoza
Is it possible to load perl modules?

Brad Fitzpatrick

unread,
May 8, 2011, 8:19:36 AM5/8/11
to golan...@googlegroups.com, Ondekoza
Yes, including XS (C) ones.  There's a test for that.  Here's Data::Dumper, which uses XS:

func TestDynamicLoading(t *testing.T) {
perl := NewInterpreter()
got := perl.EvalString(`use Data::Dumper; Dumper([1, "two", {3 => 4}]);`)
if !strings.Contains(got, "$VAR1") {
t.Errorf("expected $VAR1 in string, got %q", got)

bflm

unread,
May 8, 2011, 4:29:48 PM5/8/11
to golang-nuts
On May 8, 2:19 pm, Brad Fitzpatrick <bradf...@golang.org> wrote:
> Yes, including XS (C) ones.  There's a test for that.  Here's Data::Dumper,
> which uses XS:

Very nice contribution to Go, technically.

Non technically - the campher mascot is simply amazing ;-)

Miguel Pignatelli Moreno

unread,
May 9, 2011, 1:11:02 PM5/9/11
to golang-nuts
Hi all,

I have a binary file full with 32-bit unsigned longs in big-endian order, and I am trying to read some without loading the file in memory:

func GetVal ( f *os.File, gi int ) int {
pos := gi*4
var value uint8
newpos,seek_err := f.Seek(int64(pos), os.SEEK_SET)
if newpos != int64(pos) {
fmt.Fprintf(os.Stderr, "Can't seek to pos %d\n", pos)
os.Exit(1)
}
if seek_err != nil {
fmt.Fprintf(os.Stderr, "Can't seek to pos %d\n", pos)
os.Exit(1)
}
read_err := binary.Read(f, binary.BigEndian, &value)
if read_err != nil {
fmt.Fprintf(os.Stderr, "Can't read from file\n")
os.Exit(1)
}
return int(value)
}

func OpenDict(fname string) FileMap {
fh,err := os.Open(fname)
if err != nil {
fmt.Fprintf(os.Stderr, "File %s not found\n",fname)
os.Exit(1)
}
return fh
}

func main () {
dict := OpenDict("/path/to/binary/file")

pos := 213415
val := GetVal(dict, gi)
fmt.Printf("%d\n", val)
}

I am getting "0"s all the time (regardless the pos and the asssociated value in the file).
What am I doing wrong?

Thanks in advance,

M;

Russ Cox

unread,
May 9, 2011, 1:16:09 PM5/9/11
to Miguel Pignatelli Moreno, golang-nuts
>        var value uint8

Shouldn't this be uint32?

Miguel Pignatelli Moreno

unread,
May 9, 2011, 3:02:29 PM5/9/11
to Russ Cox, golang-nuts

El 09/05/2011, a las 18:16, Russ Cox escribió:

>> var value uint8
>
> Shouldn't this be uint32?
>

Ooops... I have been copy-pasting from a previous version of the function and didn't realized this.

Sorry for not figuring out before!

M;

Reply all
Reply to author
Forward
0 new messages