Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

rb_class_new_instance behaves strange

2 views
Skip to first unread message

Simon Strandgaard

unread,
Apr 15, 2003, 6:58:35 AM4/15/03
to
My code is behaving different, when im doing this change:

# (a)
VALUE self = rb_class_new_instance(a.n, a.argv, klass);

to:

# (b)
VALUE self = rb_funcall2(klass, rb_intern("new"), a.n, a.argv);


What is the difference ???

Problem: with (a) then we cannot inheirit from a SWIG class.
Solution: with (b) then inheiritance works fine.


Why does this make a difference ???

--
Simon Strandgaard

nobu....@softhome.net

unread,
Apr 15, 2003, 7:16:55 AM4/15/03
to
Hi,

At Tue, 15 Apr 2003 20:02:56 +0900,


Simon Strandgaard wrote:
> My code is behaving different, when im doing this change:
>
> # (a)
> VALUE self = rb_class_new_instance(a.n, a.argv, klass);
>
> to:
>
> # (b)
> VALUE self = rb_funcall2(klass, rb_intern("new"), a.n, a.argv);
>
>
> What is the difference ???

(a) passes the given block but (b) doesn't, in normal case.

> Problem: with (a) then we cannot inheirit from a SWIG class.
> Solution: with (b) then inheiritance works fine.

How do they work fine or don't?
And which version of ruby?

--
Nobu Nakada

Simon Strandgaard

unread,
Apr 15, 2003, 7:39:04 AM4/15/03
to

OK. This is what im trying to do.
note: "Embed::Redirect" is a SWIG class.

> cat test.rb
class RubyView < Embed::Redirect
def initialize
super
end
def insert
repaint
end
end
>

If I try instantiate this "RubyView" class with (a), then it doesn't work
and Im getting a error from ruby (sorry its converted into a c++exception).

EXCEPTION (RUBY):
name=cannot invoke ruby-function
where=./a.rb:6
class=TypeError
message=wrong argument type RubyView (expected Data)
backtrace= from ./a.rb:6:in `repaint'
from ./a.rb:6:in `insert'


If I try instantiate with (b) then everything works (no errors).


> And which version of ruby?

> ruby -v
ruby 1.8.0 (2003-03-03) [i386-freebsd5.0]
>


--
Simon Strandgaard

Simon Strandgaard

unread,
Apr 15, 2003, 7:55:50 AM4/15/03
to

BTW this is the SWIG im using :-)


> swig -version
SWIG Version 1.3.18
Copyright (c) 1995-1998
University of Utah and the Regents of the University of California
Copyright (c) 1998-2002
University of Chicago
Compiled with g++

Please see http://www.swig.org for reporting bugs and further information
>

--
Simon Strandgaard

ts

unread,
Apr 15, 2003, 9:11:24 AM4/15/03
to
>>>>> "S" == Simon Strandgaard <0bz63fz3...@sneakemail.com> writes:

S> BTW this is the SWIG im using :-)

Can you give the code generated by SWIG, if it's not too long or send me
it in private email

Guy Decoux


Simon Strandgaard

unread,
Apr 15, 2003, 9:40:40 AM4/15/03
to

fetch this tar.gz file:
http://metaeditor.sourceforge.net/embed/rubyembed-0.1.tar.gz


the SWIG generated file is
rubyembed-0.1.tar.gz/source/redirect_wrap.cpp


--
Simon Strandgaard

ts

unread,
Apr 15, 2003, 10:34:33 AM4/15/03
to
>>>>> "S" == Simon Strandgaard <0bz63fz3...@sneakemail.com> writes:

S> http://metaeditor.sourceforge.net/embed/rubyembed-0.1.tar.gz

I've not found 1.3.18, at sourceforge there is only .19, .17

pigeon% swig -version

SWIG Version 1.3.19


Copyright (c) 1995-1998
University of Utah and the Regents of the University of California
Copyright (c) 1998-2002
University of Chicago
Compiled with g++

Please see http://www.swig.org for reporting bugs and further information

pigeon%

pigeon% ruby -v
ruby 1.8.0 (2003-04-10) [i686-linux]
pigeon%

pigeon% tail -18 rubycpp.cpp


VALUE self = rb_class_new_instance(a.n, a.argv, klass);

//VALUE self = rb_funcall2(klass, rb_intern("new"), a.n, a.argv);
return self;
}

VALUE New(string klass) {
NewArguments arg(klass.c_str(), 0, 0);
int error = 0;
VALUE self = rb_protect(NewWrap, reinterpret_cast<VALUE>(&arg), &error);
if(error) {
std::ostringstream o;
o << "error creating " << klass;
throw RUBY_CPP::RubyError::Create(o.str());
}
return self;
}

} // end of namespace RUBY_CPP
pigeon%

and I've no problems


pigeon% ./testswig
main: enter
test.rb: enter
test.rb: leave
aeditorlib: started (no-swig)
-- Test1 simple ----------------------
view.ctor: enter
redirect.ctor: hello
rubyview.initialize: overloaded
objects += 401f530c
view.ctor: leave
view.insert: enter
rubyview.insert: enter
redirect.repaint: enter
viewqt.repaint: bingo
redirect.repaint: leave
rubyview.insert: leave
view.insert: leave
view.dtor: enter
objects -= 401f530c
view.dtor: leave
-- Test2 multiple instances ----------------------
[1]
view.ctor: enter
redirect.ctor: hello
rubyview.initialize: overloaded
objects += 401f4858
view.ctor: leave
view.insert: enter
rubyview.insert: enter
redirect.repaint: enter
viewqt.repaint: bingo
redirect.repaint: leave
rubyview.insert: leave
view.insert: leave
[2]
view.ctor: enter
redirect.ctor: hello
rubyview.initialize: overloaded
objects += 401f4808
view.ctor: leave
view.insert: enter
rubyview.insert: enter
redirect.repaint: enter
viewqt.repaint: bingo
redirect.repaint: leave
rubyview.insert: leave
view.insert: leave
[3]
view.insert: enter
rubyview.insert: enter
redirect.repaint: enter
viewqt.repaint: bingo
redirect.repaint: leave
rubyview.insert: leave
view.insert: leave
[4]
view.ctor: enter
redirect.ctor: hello
rubyview.initialize: overloaded
objects += 401f47b8
view.ctor: leave
view.insert: enter
rubyview.insert: enter
redirect.repaint: enter
viewqt.repaint: bingo
redirect.repaint: leave
rubyview.insert: leave
view.insert: leave
[5]
view.dtor: enter
objects -= 401f47b8
view.dtor: leave
view.dtor: enter
objects -= 401f4808
view.dtor: leave
view.dtor: enter
objects -= 401f4858
view.dtor: leave
-- End ------------------------------------
redirect.dtor: hello
redirect.dtor: hello
redirect.dtor: hello
redirect.dtor: hello
aeditorlib: stopped
main: leave (0)
pigeon%

Guy Decoux

Simon Strandgaard

unread,
Apr 15, 2003, 11:08:02 AM4/15/03
to
On Wed, 16 Apr 2003 00:34:33 +0900, ts wrote:

I have just installed the newest SWIG version 1.3.19 and generated a new
wrapper. But it still FAILs!!

> ./testswig
main: enter
test.rb: enter
test.rb: leave

aeditorlib: started (with-swig)


-- Test1 simple ----------------------
view.ctor: enter

rubyview.initialize: overloaded
redirect.ctor: hello
objects += 8108cf0


view.ctor: leave
view.insert: enter
rubyview.insert: enter

view.dtor: enter
objects -= 8108cf0
view.dtor: leave


EXCEPTION (RUBY):
name=cannot invoke ruby-function

where=./test.rb:17


class=TypeError
message=wrong argument type RubyView (expected Data)

backtrace= from ./test.rb:17:in `repaint'
from ./test.rb:17:in `insert'

main: leave (1)


> tail -18 rubycpp.cpp
VALUE self = rb_class_new_instance(a.n, a.argv, klass);
//VALUE self = rb_funcall2(klass, rb_intern("new"), a.n, a.argv);
return self;
}

VALUE New(string klass) {
NewArguments arg(klass.c_str(), 0, 0);
int error = 0;
VALUE self = rb_protect(NewWrap, reinterpret_cast<VALUE>(&arg), &error);
if(error) {
std::ostringstream o;
o << "error creating " << klass;
throw RUBY_CPP::RubyError::Create(o.str());
}
return self;
}

} // end of namespace RUBY_CPP

> swig -version

SWIG Version 1.3.19
Copyright (c) 1995-1998
University of Utah and the Regents of the University of California
Copyright (c) 1998-2002
University of Chicago
Compiled with g++

Please see http://www.swig.org for reporting bugs and further information

> ruby -v
ruby 1.8.0 (2003-03-03) [i386-freebsd5.0]
>


> and I've no problems

There is 2 binaries, I think you executed the wrong one.


>
> pigeon% ./testswig
> main: enter
> test.rb: enter
> test.rb: leave
> aeditorlib: started (no-swig)

^^^^^^^
^^^^^^^
If you ran the "testswig" program, it should say "with-swig"...
I think you ran the "test" program :-)

Try again :-)


--
Simon Strandgaard

nobu....@softhome.net

unread,
Apr 15, 2003, 11:32:33 AM4/15/03
to
Hi,

At Tue, 15 Apr 2003 22:44:39 +0900,


Simon Strandgaard wrote:
> > S> BTW this is the SWIG im using :-)
> >
> > Can you give the code generated by SWIG, if it's not too long or send me
> > it in private email
> >
> > Guy Decoux
>
> fetch this tar.gz file:
> http://metaeditor.sourceforge.net/embed/rubyembed-0.1.tar.gz
>
>
> the SWIG generated file is
> rubyembed-0.1.tar.gz/source/redirect_wrap.cpp

SWIG doesn't seem to use rb_define_alloc_func(), so allocator
of Object is used by rb_class_new_instance(). "new" works fine
because SWIG redefines Redirect.new (but it is deprecated now).

--
Nobu Nakada

Simon Strandgaard

unread,
Apr 15, 2003, 12:13:35 PM4/15/03
to


Is this a problem SWIG ?
Or is this a problem with RUBY ?

--
Simon Strandgaard

Lyle Johnson

unread,
Apr 15, 2003, 12:50:03 PM4/15/03
to nobu....@softhome.net
[Nobu said:]

>> SWIG doesn't seem to use rb_define_alloc_func(), so allocator
>> of Object is used by rb_class_new_instance(). "new" works fine
>> because SWIG redefines Redirect.new (but it is deprecated now).

[And then Simon responded:]

> Is this a problem SWIG ?
> Or is this a problem with RUBY ?

[And now Lyle says:]

So far, I've purposely avoided making any changes to support Ruby's new
allocation scheme since (at least in its initial implementation in Ruby
1.7.x) there seemed to be some problems. There's also the issue of
backwards compatibility with Ruby versions 1.6.x and earlier. If SWIG is
to generate code that will compile under both Ruby 1.6 and Ruby 1.8,
there will presumably need to be a compile-time check of the Ruby
version number.

Since, as Nobu notes, redefining 'new' works for both Ruby 1.6 and 1.8,
I've left it that way until now. If Matz, Nobu and others feel confident
about the new allocation implementation in 1.8 I can revisit the issue.

nobu....@softhome.net

unread,
Apr 15, 2003, 12:35:24 PM4/15/03
to
Hi,

At Wed, 16 Apr 2003 01:25:33 +0900,


Simon Strandgaard wrote:
> > SWIG doesn't seem to use rb_define_alloc_func(), so allocator
> > of Object is used by rb_class_new_instance(). "new" works fine
> > because SWIG redefines Redirect.new (but it is deprecated now).
>
> Is this a problem SWIG ?

SWIG (1.3.19 at least) seems to not support ruby 1.8.

--
Nobu Nakada

ts

unread,
Apr 15, 2003, 12:52:31 PM4/15/03
to
>>>>> "L" == Lyle Johnson <ly...@users.sourceforge.net> writes:

L> 1.7.x) there seemed to be some problems. There's also the issue of
L> backwards compatibility with Ruby versions 1.6.x and earlier. If SWIG is
L> to generate code that will compile under both Ruby 1.6 and Ruby 1.8,
L> there will presumably need to be a compile-time check of the Ruby
L> version number.

Nothing new for this, from bdb

#if RUBY_VERSION_CODE < 180
#define StringValue(x,y) rb_str2cstr(x,y)
#define StringValuePtr(x) STR2CSTR(x)
#define SafeStringValue(x) Check_SafeStr(x)
#endif

#if RUBY_VERSION_CODE >= 180
rb_define_alloc_func(bdb_cEnv, bdb_env_s_alloc);
#else
rb_define_singleton_method(bdb_cEnv, "allocate", bdb_env_s_alloc, 0);
#endif

etc, etc


Guy Decoux


Yukihiro Matsumoto

unread,
Apr 15, 2003, 12:53:21 PM4/15/03
to
Hi,

In message "Re: rb_class_new_instance behaves strange"


on 03/04/16, Lyle Johnson <ly...@users.sourceforge.net> writes:

|Since, as Nobu notes, redefining 'new' works for both Ruby 1.6 and 1.8,
|I've left it that way until now. If Matz, Nobu and others feel confident
|about the new allocation implementation in 1.8 I can revisit the issue.

I'm confident. Tell me if you see any problem that I don't know.

matz.

nobu....@softhome.net

unread,
Apr 15, 2003, 1:17:09 PM4/15/03
to
Hi,

At Wed, 16 Apr 2003 01:45:49 +0900,


Lyle Johnson wrote:
> So far, I've purposely avoided making any changes to support Ruby's
> new allocation scheme since (at least in its initial implementation in
> Ruby 1.7.x) there seemed to be some problems. There's also the issue
> of backwards compatibility with Ruby versions 1.6.x and earlier. If
> SWIG is to generate code that will compile under both Ruby 1.6 and
> Ruby 1.8, there will presumably need to be a compile-time check of the
> Ruby version number.

1.8 defines HAVE_RB_DEFINE_ALLOC_FUNC for that purpose.


--- Source/Modules/ruby.cxx~ Tue Mar 18 01:52:37 2003
+++ Source/Modules/ruby.cxx Wed Apr 16 02:03:09 2003
@@ -479,6 +479,11 @@ public:
break;
case CONSTRUCTOR_ALLOCATE:
+ Printv(s, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n", NIL);
+ Printv(s, tab4, "rb_define_alloc_func(", klass->vname,
+ ", ", wname, ");\n", NIL);
+ Printv(s, "#else\n", NIL);
Printv(s, tab4, "rb_define_singleton_method(", klass->vname,
", \"new\", ", wname, ", -1);\n", NIL);
+ Printv(s, "#endif\n", NIL);
Replaceall(klass->init,"$allocator", s);
break;
@@ -830,5 +835,7 @@ public:
need_result = 1;
Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t)));
+ Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
+ Printf(f->code, "#endif\n");
} else if (current == CONSTRUCTOR_INITIALIZE) {
need_result = 1;
@@ -1329,6 +1336,8 @@ public:

String *s = NewString("");
+ Printv(s, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n", NIL);
Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname,
"), \"new\");\n", NIL);
+ Printv(s, "#endif\n", NIL);
Replaceall(klass->init,"$allocator", s);
Replaceall(klass->init,"$initializer", "");

--
Nobu Nakada

Lyle Johnson

unread,
Apr 15, 2003, 3:58:08 PM4/15/03
to
ts wrote:

> Nothing new for this, from bdb

<snip>

Thanks very much, Guy; I've incorporated this into the SWIG CVS and it
should be available for SWIG 1.3.20.

Lyle Johnson

unread,
Apr 15, 2003, 4:02:39 PM4/15/03
to
nobu....@softhome.net wrote:

> 1.8 defines HAVE_RB_DEFINE_ALLOC_FUNC for that purpose.

<snip patches>

Thanks very much for the patches, Nobu; I've incorporated them into the
SWIG CVS and they should be available in SWIG 1.3.20.

One aspect of this change is still unclear to me: what is now the
correct way to indicate that an extension class is an abstract class?
Previously, SWIG was either redefining 'new' for concrete extension
classes, or undefining 'new' for abstract extension classes.

nobu....@softhome.net

unread,
Apr 15, 2003, 5:21:04 PM4/15/03
to
Hi,

At Wed, 16 Apr 2003 04:47:13 +0900,


Lyle Johnson wrote:
> One aspect of this change is still unclear to me: what is now the
> correct way to indicate that an extension class is an abstract class?
> Previously, SWIG was either redefining 'new' for concrete extension
> classes, or undefining 'new' for abstract extension classes.

Sorry, I missed it. You can make them abstract by undefining
allocator with rb_undef_alloc_func().

Please replace all STR2CSTR to StringValue, and apply this
patch.


--- Lib/ruby/rubyhead.swg~ Wed Feb 26 04:22:36 2003
+++ Lib/ruby/rubyhead.swg Wed Apr 16 06:11:34 2003
@@ -76,3 +76,26 @@ typedef struct {
void (*destroy)(void *);
} swig_class;
+
+/* Don't use for expressions have side effect */
+#ifndef RB_STRING_VALUE
+#define RB_STRING_VALUE(s) (TYPE(s) == T_STRING ? (s) : (*(volatile VALUE *)&(s) = rb_str_to_str(s)))
+#endif
+#ifndef StringValue
+#define StringValue(s) RB_STRING_VALUE(s)
+#endif
+#ifndef StringValuePtr
+#define StringValuePtr(s) RSTRING(RB_STRING_VALUE(s))->ptr
+#endif
+#ifndef StringValueLen
+#define StringValueLen(s) RSTRING(RB_STRING_VALUE(s))->len
+#endif
+#define SafeStringValue(v) do {\
+ StringValue(v);\
+ rb_check_safe_str(v);\
+} while (0)
+
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
+#define rb_define_alloc_func(klass, func) rb_define_singleton_method(klass, "new", func, -1)
+#define rb_undefine_alloc_func(klass) rb_undef_method(CLASS_OF(klass), "new")
+#endif


--- Source/Modules/ruby.cxx~ Tue Mar 18 01:52:37 2003

+++ Source/Modules/ruby.cxx Wed Apr 16 06:11:48 2003
@@ -479,6 +479,6 @@ public:
break;
case CONSTRUCTOR_ALLOCATE:
- Printv(s, tab4, "rb_define_singleton_method(", klass->vname,
- ", \"new\", ", wname, ", -1);\n", NIL);


+ Printv(s, tab4, "rb_define_alloc_func(", klass->vname,
+ ", ", wname, ");\n", NIL);

Replaceall(klass->init,"$allocator", s);
break;

@@ -830,5 +830,7 @@ public:


need_result = 1;
Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t)));
+ Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
+ Printf(f->code, "#endif\n");
} else if (current == CONSTRUCTOR_INITIALIZE) {
need_result = 1;

@@ -1329,6 +1331,5 @@ public:



String *s = NewString("");

- Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname,
- "), \"new\");\n", NIL);
+ Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL);

Steve Hart

unread,
Apr 15, 2003, 9:12:49 PM4/15/03
to
nobu....@softhome.net wrote in message news:<200304151635....@sharui.nakada.kanuma.tochigi.jp>...

And the practical upshot is?
Mind you, at least you guy's got to look at simon's tutorial. What do
you think. Any comments for us humble users :-)

Lyle Johnson

unread,
Apr 16, 2003, 6:45:06 PM4/16/03
to
nobu....@softhome.net wrote:

> Sorry, I missed it. You can make them abstract by undefining
> allocator with rb_undef_alloc_func().

OK.

> Please replace all STR2CSTR to StringValue, and apply this
> patch.

Don't you mean replace all STR2CSTR with StringValuePtr? I think
StringValue() returns a String object (a VALUE) while StringValuePtr()
returns the underlying C character array.

nobu....@softhome.net

unread,
Apr 16, 2003, 10:21:27 PM4/16/03
to
Hi,

At Thu, 17 Apr 2003 07:35:39 +0900,


Lyle Johnson wrote:
> > Please replace all STR2CSTR to StringValue, and apply this
> > patch.
>
> Don't you mean replace all STR2CSTR with StringValuePtr? I think
> StringValue() returns a String object (a VALUE) while StringValuePtr()
> returns the underlying C character array.

You're correct of course. Just my mistake, sorry.

--
Nobu Nakada

Simon Strandgaard

unread,
Apr 17, 2003, 8:22:29 PM4/17/03
to
Thanks everyone for solving this problem :-)

BTW. When can we expect to see SWIG 3.1.20 ?


--
Simon Strandgaard


Lyle Johnson

unread,
Apr 17, 2003, 9:57:04 PM4/17/03
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Simon Strandgaard wrote:

| When can we expect to see SWIG 1.3.20?

Don't know, but you don't have to wait. Just follow the instructions at
this page:

http://www.swig.org/cvs.html

to check out the CVS sources, which have the latest fixes since 1.3.19.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQE+n1twRy8FwLkdsRcRAi1TAJoCad1LZtzVO7vYrZnDDex8Tt3KXQCdEAnC
72LSvnOb4IujgSITzU/ek9A=
=wVCw
-----END PGP SIGNATURE-----

0 new messages