[ARTICLE] Extending Ruby with C

An article from Garrett Rooney just appeared at OnLamp.com
you can read it at
http://www.onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html

As you may understand it talks about how to write C extensions for ruby.
It's great to see more ruby in online magazines, who's the next one ? :slight_smile:

PS
I'm not related to the author or the page, I just found it and noticed the author is not a frequent writer here, so I forwarded the notice :slight_smile:

gabriele renzi <rff_rff@remove-yahoo.it> wrote in news:wQknd.40392
$Ni.1406459@twister1.libero.it:

As you may understand it talks about how to write C extensions for ruby.
It's great to see more ruby in online magazines, who's the next one ? :slight_smile:

I don't know if its been mentioned before on this list, but german Linux
Magazine (I think you can buy it in countries like Germany, Austria,
Switzerland, Italy and Spain) has a feature on scripting languages in its
4th quartal/2004 issue. One of the languages is Ruby, I am not quite trough
reading it, but at least it gives all the important pointers.

The articles seem to be written by Armin Roehrl and Stefan Schmiedl.

Just thought I'd drop that in..kaspar

hand manufactured code - www.tua.ch/ruby

This is actually a very good article. The example extension, GenX4R,
is small enough that you can get your head around the problem. The
writing is clear and complete. The author is clearly an experienced C
programmer and seems to have a good understanding of Ruby. Not only
that, he's gone to the trouble of turning the example into a real
RubyForge project: http://genx4r.rubyforge.org. Thanks, Mr. Rooney!

(No, I'm not related to Mr. Rooney :slight_smile: but I have some experience with
C-language Ruby extensions and I appreciate good writing when I see
it.)

···

On Fri, 19 Nov 2004 11:31:40 GMT, gabriele renzi <rff_rff@remove-yahoo.it> wrote:

An article from Garrett Rooney just appeared at OnLamp.com
you can read it at
Radar – O’Reilly

gabriele renzi <rff_rff@remove-yahoo.it> wrote in message news:<wQknd.40392$Ni.1406459@twister1.libero.it>...

An article from Garrett Rooney just appeared at OnLamp.com
you can read it at
Radar – O’Reilly

As you may understand it talks about how to write C extensions for ruby.
It's great to see more ruby in online magazines, who's the next one ? :slight_smile:

PS
I'm not related to the author or the page, I just found it and noticed
the author is not a frequent writer here, so I forwarded the notice :slight_smile:

One thing I wish C extension authors would stop doing is manually
counting variable length argument lists. From the article:

static VALUE
writer_begin_element (int argc, VALUE *argv, VALUE self)
{
  genxWriter w;
  VALUE xmlns, name;

  switch (argc):

....

If I'm not mistaken, this style of argument checking has already led
to more than one bug in the Ruby source code itself. Knock it off and
use rb_scan_args(). Also, I find that starting all VALUE variables
with 'rb' leads to clearer code, since it makes it immediately obvious
which values are Ruby VALUE's versus C variables.

static VALUE
writer_begin_element (int argc, VALUE *argv, VALUE self)
{
  genxWriter w;
  VALUE rbName, rbXmlns;
  
  /* One mandatory argument, one optional argument */
  rb_scan_args(argc,argv,"11",&rbName,&rbXmlns);
          
  Check_Type(rbName,T_STRING);
  Check_Type(rbXmlns,T_STRING);

....

This is both shorter, more concise and easier to read all in one shot.
It's also a smarter API, since in both cases the name is mandatory,
while the namespace is optional, afaict. So, now the front end looks
like this:

Genx::Writer#begin_element(name,namespace=nil)

Other than a minor modification in GENX4R_ERR, checking against Qnil
vs 0, this code is identical. No big, ugly switch. No need to
manually raise an ArgumentError if the arg count is wrong. Nice and
tidy.

Regards,

Dan

Kaspar Schiess wrote:

...
I don't know if its been mentioned before on this list, but german Linux Magazine (I think you can buy it in countries like Germany, Austria, Switzerland, Italy and Spain) has a feature on scripting languages in its 4th quartal/2004 issue. One of the languages is Ruby, I am not quite trough reading it, but at least it gives all the important pointers.

I picked up a copy while I was in Germany last month, and was amused to see that, among the "scripting" languages discussed, was Lisp.

The articles seem to be written by Armin Roehrl and Stefan Schmiedl.

Yes, the outstanding folks who organize EuRuKo, the European Ruby conferences.

James

gabriele renzi <rff_rff@remove-yahoo.it> wrote in message news:<wQknd.40392$Ni.1406459@twister1.libero.it>...

An article from Garrett Rooney just appeared at OnLamp.com
you can read it at
Radar – O’Reilly
(....)

One thing I wish C extension authors would stop doing is manually
counting variable length argument lists. From the article:

static VALUE
writer_begin_element (int argc, VALUE *argv, VALUE self)
{
  genxWriter w;
  VALUE xmlns, name;

  switch (argc):

....

If I'm not mistaken, this style of argument checking has already led
to more than one bug in the Ruby source code itself. Knock it off and
use rb_scan_args(). Also, I find that starting all VALUE variables
with 'rb' leads to clearer code, since it makes it immediately obvious
which values are Ruby VALUE's versus C variables.

Sounds like a good practice.

static VALUE
writer_begin_element (int argc, VALUE *argv, VALUE self)
{
  genxWriter w;
  VALUE rbName, rbXmlns;

  /* One mandatory argument, one optional argument */
  rb_scan_args(argc,argv,"11",&rbName,&rbXmlns);

  Check_Type(rbName,T_STRING);
  Check_Type(rbXmlns,T_STRING);

....

If you use camel case for your variable names this seems OK, but I would worry about creating conflicts with existing Ruby method names and global variables - since they all start with 'rb'.

This is both shorter, more concise and easier to read all in one shot.
It's also a smarter API, since in both cases the name is mandatory,
while the namespace is optional, afaict. So, now the front end looks
like this:

Genx::Writer#begin_element(name,namespace=nil)

Other than a minor modification in GENX4R_ERR, checking against Qnil
vs 0, this code is identical. No big, ugly switch. No need to
manually raise an ArgumentError if the arg count is wrong. Nice and
tidy.

I have found that making judicious use of StingValue(), NUM2LONG(), rb_Array(), and friends has advantages over using Check_Type() - you get better error messages and you add compatibility with other extensions/classes that make use "to_str", "to_int", "to_a", ... the later being a big plus.

-Charlie

···

On Nov 19, 2004, at 11:58 AM, Daniel Berger wrote:

Kaspar Schiess wrote:

...
I don't know if its been mentioned before on this list, but german Linux
Magazine (I think you can buy it in countries like Germany, Austria,
Switzerland, Italy and Spain) has a feature on scripting languages in its
4th quartal/2004 issue. One of the languages is Ruby, I am not quite trough
reading it, but at least it gives all the important pointers.

I picked up a copy while I was in Germany last month, and was amused to
see that, among the "scripting" languages discussed, was Lisp.

IIRC, they wanted to produce a special on "special" languages.
Just to show people that there is more than C, Java and Perl.
Right in the middle of the work they stumbled upon our second
book "Produktiver Programmieren", which probably doesn't sell
either but has the same idea behind it.

I'm really all for using different things, just to learn something new.
One of my favourite tools currently is RetroForth (www.retroforth.org),
which (on linux) comes at a whopping 4535 bytes (ELF-executable). This
week I added some stuff to produce XSL-FO files from a relatively
compact description. The standalone executable is about 6kB large
and has "only" the linux kernel as external dependency, IIRC.

It's amazing what you can do with such a small amount of code.

The articles seem to be written by Armin Roehrl and Stefan Schmiedl.

Yes, the outstanding folks who organize EuRuKo, the European Ruby
conferences.

Thanks, James. But to give credit where it's due, Armin and Michael
Neumann did most of the work.

s.

···

On Sat, 20 Nov 2004 00:37:35 +0900, James Britt <jamesUNDERBARb@neurogami.com> wrote: