--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi.
I'm converting some of my ruby code to C extension for better perfomance.
I ran into problems with executing methods that take blocks.
I.e. in ruby i have
string.gsub!(/regexp/) { |subst| ... }
and i can't find the way to translate it to C. I tried to search through
ruby-talk archives, but I couldn't find anything usefull.
As far as I was looking at problem, I found rb_iterate, rb_yield, but I
couldn't clearly understand what's their purpose, and how to get them all
together to achieve what I want.
Could somebody please explain me how can I implement this ruby code in C?
I'd really appreciate any help. Thanks in advance!
I was surprised to see that rb_funcall propagates the block passed with
rb_iterate, so there's 2 solutions (attached).
--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Linux! Guerrilla UNIX Development Venimus, Vidimus, Dolavimus.
-- Mark A. Horton KA4YBR, (e-mail address removed)
--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="extconf.rb"
require "mkmf"
create_makefile("gsub_example")
--nFreZHaLTZJo0R7j
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="gsub_example.c"
#include <ruby.h>
#include <stdio.h>
VALUE mCTest;
static
VALUE
block(VALUE args)
{
VALUE str = rb_ary_entry(args, 0);
Check_Type(str, T_STRING);
printf("Inside block, with string: %s.\n", RSTRING(str)->ptr);
return rb_funcall(str, rb_intern("upcase"), 0);
}
static
VALUE
block2(VALUE str)
{
Check_Type(str, T_STRING);
printf("Inside block, with string: %s.\n", RSTRING(str)->ptr);
return rb_funcall(str, rb_intern("upcase"), 0);
}
static
VALUE
foo(VALUE self, VALUE str, VALUE re)
{
VALUE proc;
proc = rb_proc_new(block, Qnil);
return rb_funcall(str, rb_intern("_gsub!"), 2, re, proc);
}
static
VALUE
call_gsub(VALUE args)
{
VALUE str, re;
str = rb_ary_entry(args, 0);
re = rb_ary_entry(args, 1);
return rb_funcall(str, rb_intern("gsub!"), 1, re);
}
static
VALUE
foo2(VALUE self, VALUE str, VALUE re)
{
VALUE args;
args = rb_ary_new();
rb_ary_push(args, str);
rb_ary_push(args, re);
return rb_iterate(call_gsub, args, block2, str);
}
void
Init_gsub_example()
{
mCTest = rb_define_module("CTest");
rb_define_singleton_method(mCTest, "foo", foo, 2);
rb_define_singleton_method(mCTest, "foo2", foo2, 2);
rb_eval_string("class String; def _gsub!(re,block); gsub!(re,&block) end end");
}
--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="tst.rb"
require "gsub_example"
a = "hello, world!"
CTest.foo(a, /[ehl]/)
p a
b = "hello, world!"
CTest.foo2(b, /[ehl]/)
p b
--nFreZHaLTZJo0R7j--