Ruby Interface of Erlang

  • Follow


[Note:  parts of this message were removed to make it a legal post.]

Hello, erveyone,I just start a new project called erlix,the ruby interface
for erlang,at http://code.google.com/p/erlix ,you may need it.

Erlix can help you communicating with the erlang-node, you can write
distributed programs with ruby and erlang easily.

Just read its api docs if you need it.

-- 
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/27/2009 3:49:48 PM

On Monday 27 April 2009 10:49:48 KDr2 wrote:
> Erlix can help you communicating with the erlang-node, you can write
> distributed programs with ruby and erlang easily.

How does this compare to Erlectricity?

http://code.google.com/p/erlectricity

0
Reply ninja (512) 4/27/2009 10:24:19 PM


[Note:  parts of this message were removed to make it a legal post.]

1.Erlectricity interact with Erlang through the ports system. If you are an
Erlang programmer,you will feel confused about it:
    Where are my Erlang-Terms? How to  match two Terms? How to make my
ruby-process an erlang-node? so i start the project erlix.
2.erlix is based on the erl_interface, all its api is the same as
erl_interface:

 irb(main):001:0> require "erlix"
=> true
irb(main):002:0>
list=ErlixList.new([ErlixAtom.new("erlatom"),ErlixInt.new(2),ErlixFloat.new(3.0)])
=> #<ErlixList:0xb7c738e8>
irb(main):003:0> list.puts
[erlatom,2,3.000000]
=> nil
irb(main):004:0> list.match("[A,2,B]")
=> true
irb(main):005:0> list.match("[A,3,B]")
=> false
irb(main):006:0> b=list.mget("[Atom,_,_]","Atom")
=> erlatom
irb(main):007:0> b.class
=> ErlixAtom
irb(main):008:0> ObjectSpace.each_object(Class).inject([]){|a,i|a<< i if
i.ancestors.any?{|k|k==ErlixTerm};a}
=> [ErlixBinary, ErlixTuple, ErlixList, ErlixAtom, ErlixRef, ErlixPid,
ErlixFloat, ErlixUInt, ErlixInt]
irb(main):009:0>

And... use erlix, you can make you ruby-process an Erlang-Node(read the test
code in the src-package) hehe

:)




On Tue, Apr 28, 2009 at 6:24 AM, David Masover <ninja@slaphack.com> wrote:

> Erlectricity




-- 
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/28/2009 1:43:56 AM

[Note:  parts of this message were removed to make it a legal post.]

I release erlix-v0.3 today:

bugfix:

IO block bug in
ErlixConnection?<http://code.google.com/p/erlix/w/edit/ErlixConnection>#erecv


feature:

   1. ErlixList?
<http://code.google.com/p/erlix/w/edit/ErlixList>#new("string")

   2. ErlixConnection?<http://code.google.com/p/erlix/w/edit/ErlixConnection>#close

   3. ErlixConnection?<http://code.google.com/p/erlix/w/edit/ErlixConnection>#closed?

   4. ErlixConnection?<http://code.google.com/p/erlix/w/edit/ErlixConnection>
   #rpc("module","function",ErlixTermList?<http://code.google.com/p/erlix/w/edit/ErlixTermList>)

   5. ErlixConnection?<http://code.google.com/p/erlix/w/edit/ErlixConnection>#peer


see the section Erlix RPC on
http://code.google.com/p/erlix/wiki/ErlixTutorial


On Tue, Apr 28, 2009 at 9:43 AM, KDr2 <kdr2@x-macro.com> wrote:

> 1.Erlectricity interact with Erlang through the ports system. If you are an
> Erlang programmer,you will feel confused about it:
>    Where are my Erlang-Terms? How to  match two Terms? How to make my
> ruby-process an erlang-node? so i start the project erlix.
> 2.erlix is based on the erl_interface, all its api is the same as
> erl_interface:
>
>  irb(main):001:0> require "erlix"
> => true
> irb(main):002:0>
>
> list=ErlixList.new([ErlixAtom.new("erlatom"),ErlixInt.new(2),ErlixFloat.new(3.0)])
> => #<ErlixList:0xb7c738e8>
> irb(main):003:0> list.puts
> [erlatom,2,3.000000]
> => nil
> irb(main):004:0> list.match("[A,2,B]")
> => true
> irb(main):005:0> list.match("[A,3,B]")
> => false
> irb(main):006:0> b=list.mget("[Atom,_,_]","Atom")
> => erlatom
> irb(main):007:0> b.class
> => ErlixAtom
> irb(main):008:0> ObjectSpace.each_object(Class).inject([]){|a,i|a<< i if
> i.ancestors.any?{|k|k==ErlixTerm};a}
> => [ErlixBinary, ErlixTuple, ErlixList, ErlixAtom, ErlixRef, ErlixPid,
> ErlixFloat, ErlixUInt, ErlixInt]
> irb(main):009:0>
>
> And... use erlix, you can make you ruby-process an Erlang-Node(read the
> test
> code in the src-package) hehe
>
> :)
>
>
>
>
> On Tue, Apr 28, 2009 at 6:24 AM, David Masover <ninja@slaphack.com> wrote:
>
> > Erlectricity
>
>
>
>
> --
> Best Regards,
>   -- KDr2, at x-macro.com.
>



-- 
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/29/2009 3:06:19 AM

KDr2 wrote:
> see the section Erlix RPC on
> http://code.google.com/p/erlix/wiki/ErlixTutorial

Just a thought: if you were to move all these constants into an Erlix 
module (e.g. Erlix::Tuple, Erlix::Int etc) then you could 'include 
Erlix' and save a lot of typing. The only conflict I can see would be 
Float, and you can always use ::Float to get the Ruby one should you 
need it.

The separate namespace can also be useful when creating objects 
dynamically:
  type = "Tuple"
  obj = Erlix.const_get(type).new

You could also consider module functions as a shortcut for constructors.

module Erlix
  # Fake implementation
  class Tuple
    def initialize(*x)
      @data = *x
    end
  end
  class Int
    def initialize(x)
      @data = x
    end
  end

  # Module functions
  def Tuple(*x)
    Tuple.new(*x)
  end
  module_function :Tuple
  def Int(*x)
    Int.new(*x)
  end
  module_function :Int
  # etc
end

include Erlix
puts Tuple(Tuple(Int(1)), Int(2)).inspect

Regards,

Brian.
-- 
Posted via http://www.ruby-forum.com/.

0
Reply b.candler (2627) 4/29/2009 1:43:36 PM

[Note:  parts of this message were removed to make it a legal post.]

Thank you for your advise :) They are very useful for me.

On Wed, Apr 29, 2009 at 9:43 PM, Brian Candler <b.candler@pobox.com> wrote:

> KDr2 wrote:
> > see the section Erlix RPC on
> > http://code.google.com/p/erlix/wiki/ErlixTutorial
>
> Just a thought: if you were to move all these constants into an Erlix
> module (e.g. Erlix::Tuple, Erlix::Int etc) then you could 'include
> Erlix' and save a lot of typing. The only conflict I can see would be
> Float, and you can always use ::Float to get the Ruby one should you
> need it.
>
> The separate namespace can also be useful when creating objects
> dynamically:
>  type = "Tuple"
>  obj = Erlix.const_get(type).new
>
> You could also consider module functions as a shortcut for constructors.
>
> module Erlix
>  # Fake implementation
>  class Tuple
>    def initialize(*x)
>      @data = *x
>    end
>  end
>  class Int
>    def initialize(x)
>      @data = x
>    end
>  end
>
>  # Module functions
>  def Tuple(*x)
>    Tuple.new(*x)
>  end
>  module_function :Tuple
>  def Int(*x)
>    Int.new(*x)
>  end
>  module_function :Int
>  # etc
> end
>
> include Erlix
> puts Tuple(Tuple(Int(1)), Int(2)).inspect
>
> Regards,
>
> Brian.
> --
> Posted via http://www.ruby-forum.com/.
>
>


-- 
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/29/2009 2:51:32 PM

BTW, I haven't been able to get it to build yet - it's stuck looking for 
-lei

$ ruby configure.rb 
--with-ei-dir=/usr/lib/erlang/lib/erl_interface-3.5.7
*** ./extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
  --with-opt-dir
  --without-opt-dir
  --with-opt-include
  --without-opt-include=${opt-dir}/include
  --with-opt-lib
  --without-opt-lib=${opt-dir}/lib
  --with-make-prog
  --without-make-prog
  --srcdir=.
  --curdir
  --ruby=/usr/local/bin/ruby
  --with-ei-dir
  --with-ei-include
  --without-ei-include=${ei-dir}/include
  --with-ei-lib
  --without-ei-lib=${ei-dir}/lib
  --with-eilib
  --without-eilib
checking for erl_init() in -lei... no
error: erl_interface not found!
$ ls /usr/lib/erlang/lib/erl_interface-3.5.7/
bin  doc  include  info  lib  src
$

I've tried various values for --with-eir without success. This is under 
Ubuntu Hardy but with erlang 12.b.3 from Intrepid. (Works fine with 
CouchDB, for example).

On a different point, I noticed the following in the C source:

  //check: all elements' must be ErlixTerm
  for(i=0;i<RARRAY(array)->len;i++){
    VALUE e=RARRAY(array)->ptr[i];
    if(!IS_ETERM(e)){
      rb_raise(rb_eTypeError,"all tuple's elements must be ErlixTerm!");
    }
  }

I think it could be useful if some automatic conversions were done here. 
e.g. Fixnum converted to Erlix[::]Int automatically, String to a List, 
maybe Array to Tuple. However maybe they're done elsewhere - as I say, 
I've not been able to run it yet.

Regards,

Brian.
-- 
Posted via http://www.ruby-forum.com/.

0
Reply b.candler (2627) 4/29/2009 3:18:07 PM

Brian Candler wrote:
> BTW, I haven't been able to get it to build yet - it's stuck looking for 
> -lei

I found the problem. In configure.rb I had to add "-pthread" to 
--with-ldflags. Without that, mkmf.log was showing the following errors:

"gcc -o conftest -I. -I/usr/local/lib/ruby/1.8/i686-linux -I./src 
-I/usr/lib/erlang/lib/erl_interface-3.5.7/include  -g -O2 conftest.c 
-L'.' -L'/usr/local/lib' -Wl,-R'/usr/local/lib' 
-L'/usr/lib/erlang/lib/erl_interface-3.5.7/lib' 
-Wl,-R'/usr/lib/erlang/lib/erl_interface-3.5.7/lib' -lei -lerl_interface 
-lruby-static -lei  -ldl -lcrypt -lm   -lc"
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `__erl_errno_place':
(.text+0x4c): undefined reference to `pthread_once'
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `__erl_errno_place':
(.text+0x7a): undefined reference to `pthread_getspecific'
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `__erl_errno_place':
(.text+0xa4): undefined reference to `pthread_setspecific'
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `__erl_errno_place':
(.text+0xb6): undefined reference to `pthread_getspecific'
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `erl_errno_key_alloc':
(.text+0x136): undefined reference to `pthread_key_create'
/usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In 
function `ei_m_trylock':
(.text+0x189): undefined reference to `pthread_mutex_trylock'
collect2: ld returned 1 exit status

However, even after successful compilation, it still didn't work due to 
a runtime linker error on "__erl_errno":

irb(main):001:0> require 'erlix'
LoadError: /usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so: 
undefined symbol: __erl_errno - 
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so
  from /usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so
  from (irb):1

After poking around header files, I decided that the way to fix this 
was:

$ make clean
$ make CPPFLAGS=-D_REENTRANT

And it happily builds and runs the sample now. I don't know how 
configure.rb should decide for itself whether -D_REENTRANT is needed or 
not.

A few more suggestions:

(1) For converting objects to strings, you should implement a "to_s" 
method, not "puts". Current behaviour is rather un-rubylike:

irb(main):008:0> t=ErlixTuple.new([a1,f,b,a2,i])
=> #<ErlixTuple:0xb7d78d74>
irb(main):009:0> t
=> #<ErlixTuple:0xb7d78d74>
irb(main):010:0> t.puts                 ## unexpected
{atom1,17.000000,#Bin,atom2,101}
=> nil
irb(main):011:0> t.to_s
=> "#<ErlixTuple:0xb7d78d74>"           ## unexpected

This would also allow you to interpolate terms into strings, e.g.

  puts "The response was #{t}"

(2) It would be helpful if ErlixTurple took a variable number of 
arguments, instead of a single array. That would let you write

   ErlixTuple.new(a1,f,b,a2,i)

This wouldn't prevent you from using an array if you like, because Ruby 
provides a 'splat' operator:

   arr = [a1,f,b,a2,i]
   ErlixTuple.new(*arr)

Anyway, keep up the good work - this is looking promising!

Regards,

Brian.
-- 
Posted via http://www.ruby-forum.com/.

0
Reply b.candler (2627) 4/29/2009 7:38:43 PM

[Note:  parts of this message were removed to make it a legal post.]

Thank you, I just hava done little update :
http://github.com/KDr2/erlix/tree/master#fn1

I will go on and on ...

On Thu, Apr 30, 2009 at 3:38 AM, Brian Candler <b.candler@pobox.com> wrote:

> Brian Candler wrote:
> > BTW, I haven't been able to get it to build yet - it's stuck looking for
> > -lei
>
> I found the problem. In configure.rb I had to add "-pthread" to
> --with-ldflags. Without that, mkmf.log was showing the following errors:
>
> "gcc -o conftest -I. -I/usr/local/lib/ruby/1.8/i686-linux -I./src
> -I/usr/lib/erlang/lib/erl_interface-3.5.7/include  -g -O2 conftest.c
> -L'.' -L'/usr/local/lib' -Wl,-R'/usr/local/lib'
> -L'/usr/lib/erlang/lib/erl_interface-3.5.7/lib'
> -Wl,-R'/usr/lib/erlang/lib/erl_interface-3.5.7/lib' -lei -lerl_interface
> -lruby-static -lei  -ldl -lcrypt -lm   -lc"
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `__erl_errno_place':
> (.text+0x4c): undefined reference to `pthread_once'
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `__erl_errno_place':
> (.text+0x7a): undefined reference to `pthread_getspecific'
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `__erl_errno_place':
> (.text+0xa4): undefined reference to `pthread_setspecific'
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `__erl_errno_place':
> (.text+0xb6): undefined reference to `pthread_getspecific'
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `erl_errno_key_alloc':
> (.text+0x136): undefined reference to `pthread_key_create'
> /usr/lib/erlang/lib/erl_interface-3.5.7/lib/libei.a(ei_pthreads.o): In
> function `ei_m_trylock':
> (.text+0x189): undefined reference to `pthread_mutex_trylock'
> collect2: ld returned 1 exit status
>
> However, even after successful compilation, it still didn't work due to
> a runtime linker error on "__erl_errno":
>
> irb(main):001:0> require 'erlix'
> LoadError: /usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so:
> undefined symbol: __erl_errno -
> /usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so
>  from /usr/local/lib/ruby/site_ruby/1.8/i686-linux/erlix.so
>  from (irb):1
>
> After poking around header files, I decided that the way to fix this
> was:
>
> $ make clean
> $ make CPPFLAGS=-D_REENTRANT
>
> And it happily builds and runs the sample now. I don't know how
> configure.rb should decide for itself whether -D_REENTRANT is needed or
> not.
>
> A few more suggestions:
>
> (1) For converting objects to strings, you should implement a "to_s"
> method, not "puts". Current behaviour is rather un-rubylike:
>
> irb(main):008:0> t=ErlixTuple.new([a1,f,b,a2,i])
> => #<ErlixTuple:0xb7d78d74>
> irb(main):009:0> t
> => #<ErlixTuple:0xb7d78d74>
> irb(main):010:0> t.puts                 ## unexpected
> {atom1,17.000000,#Bin,atom2,101}
> => nil
> irb(main):011:0> t.to_s
> => "#<ErlixTuple:0xb7d78d74>"           ## unexpected
>
> This would also allow you to interpolate terms into strings, e.g.
>
>  puts "The response was #{t}"
>
> (2) It would be helpful if ErlixTurple took a variable number of
> arguments, instead of a single array. That would let you write
>
>   ErlixTuple.new(a1,f,b,a2,i)
>
> This wouldn't prevent you from using an array if you like, because Ruby
> provides a 'splat' operator:
>
>   arr = [a1,f,b,a2,i]
>   ErlixTuple.new(*arr)
>
> Anyway, keep up the good work - this is looking promising!
>
> Regards,
>
> Brian.
> --
> Posted via http://www.ruby-forum.com/.
>
>


-- 
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/30/2009 6:00:04 AM

KDr2 wrote:
> Thank you, I just hava done little update :
> http://github.com/KDr2/erlix/tree/master#fn1

Interesting.

However I think it would be better to turn a ruby string into an erlang 
list, rather than an atom, for two reasons:

(1) It more closely matches what happens in Erlang

1> Foo = "abc".
"abc"
2> hd(Foo).
97

(2) I'm not an Erlang expert, but I think I read that Erlang has the 
same atom-exhaustion problem that Ruby has with symbols: namely that 
once an atom has been allocated it cannot be freed. So it is not a good 
idea to keep calling list_to_atom on random strings provided by 
untrusted users.

I'd still expect Ruby symbols to be mapped to atoms, of course.

Regards,

Brian.
-- 
Posted via http://www.ruby-forum.com/.

0
Reply b.candler (2627) 4/30/2009 7:28:00 AM

You're right, String should be converted to List, thanks again=EF=BC=81

On Thu, Apr 30, 2009 at 3:28 PM, Brian Candler <b.candler@pobox.com> wrote:

> KDr2 wrote:
> > Thank you, I just hava done little update :
> > http://github.com/KDr2/erlix/tree/master#fn1
>
> Interesting.
>
> However I think it would be better to turn a ruby string into an erlang
> list, rather than an atom, for two reasons:
>
> (1) It more closely matches what happens in Erlang
>
> 1> Foo =3D "abc".
> "abc"
> 2> hd(Foo).
> 97
>
> (2) I'm not an Erlang expert, but I think I read that Erlang has the
> same atom-exhaustion problem that Ruby has with symbols: namely that
> once an atom has been allocated it cannot be freed. So it is not a good
> idea to keep calling list_to_atom on random strings provided by
> untrusted users.
>
> I'd still expect Ruby symbols to be mapped to atoms, of course.
>
> Regards,
>
> Brian.
> --
> Posted via http://www.ruby-forum.com/.
>
>


--=20
Best Regards,
   -- KDr2, at x-macro.com.

0
Reply kdr2 (12) 4/30/2009 8:28:41 AM

I made some update today, and Erlix supports Ruby1.9.x now.

There're also some other changes:
1. All classes (Term/Int/List/Tuple/Atom/...) are under the Erlix module now
2. new init method for Tuple/List:
     Erlix::List.new
     Erlix::List.new(1,2,3)
     Erlix::List.new([1,2,3])

You can install it with gem or from the source, see docs at https://github.com/KDr2/erlix .

This is an alpha version(0.5.0a). If you are interesting in this, please install and do some test, find bugs and send to me, Many Thanks.
0
Reply Killy.Draw (3) 7/25/2012 3:56:38 AM

11 Replies
35 Views

(page loaded in 0.161 seconds)


Reply: