Ruby Interface of Erlang

Discussion in 'Ruby' started by KDr2, Apr 27, 2009.

  1. KDr2

    KDr2 Guest

    [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.
    KDr2, Apr 27, 2009
    #1
    1. Advertising

  2. 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
    David Masover, Apr 27, 2009
    #2
    1. Advertising

  3. KDr2

    KDr2 Guest

    [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 <> wrote:

    > Erlectricity





    --
    Best Regards,
    -- KDr2, at x-macro.com.
    KDr2, Apr 28, 2009
    #3
  4. KDr2

    KDr2 Guest

    [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 <> 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 <> wrote:
    >
    > > Erlectricity

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




    --
    Best Regards,
    -- KDr2, at x-macro.com.
    KDr2, Apr 29, 2009
    #4
  5. 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/.
    Brian Candler, Apr 29, 2009
    #5
  6. KDr2

    KDr2 Guest

    [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 <> 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.
    KDr2, Apr 29, 2009
    #6
  7. 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;
    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/.
    Brian Candler, Apr 29, 2009
    #7
  8. 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/.
    Brian Candler, Apr 29, 2009
    #8
  9. KDr2

    KDr2 Guest

    [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 <> 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.
    KDr2, Apr 30, 2009
    #9
  10. 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/.
    Brian Candler, Apr 30, 2009
    #10
  11. KDr2

    KDr2 Guest

    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 <> 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.
    KDr2, Apr 30, 2009
    #11
  12. KDr2

    KDr2 Guest

    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.
    KDr2, Jul 25, 2012
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Hobbs

    ANN: Python + Erlang = Candygram

    Michael Hobbs, Aug 25, 2004, in forum: Python
    Replies:
    2
    Views:
    321
    Dominic
    Aug 26, 2004
  2. Michael Hobbs
    Replies:
    0
    Views:
    298
    Michael Hobbs
    Oct 21, 2004
  3. Eric Torreborre

    Could Ruby be a good Erlang-like?

    Eric Torreborre, Apr 18, 2007, in forum: Ruby
    Replies:
    9
    Views:
    106
    M. Edward (Ed) Borasky
    Apr 20, 2007
  4. Woo-Kyoung Noh

    ruby classes in the erlang world

    Woo-Kyoung Noh, Jul 6, 2007, in forum: Ruby
    Replies:
    1
    Views:
    96
    Simen Edvardsen
    Jul 6, 2007
  5. Tony Arcieri
    Replies:
    0
    Views:
    105
    Tony Arcieri
    Nov 26, 2009
Loading...

Share This Page