The new allocation scheme and extensions

S

Shu-yu Guo

In 1.6, when writing an extension which required Data_Wrap_Struct, the
programmer would define the singleton method "new" to handle that. In 1.8, the
scheme seems to be to write an allocate function (to pass to
rb_define_alloc_func) then do the rest of the code in the intialize function.
Indeed, that's what Class#new does now.

So my question is, when writing extensions, is the "old" way of defining the
singleton method "new" deprecated? Are we to use the new allocate/initialize
way now?
 
Y

Yukihiro Matsumoto

Hi,

In message "The new allocation scheme and extensions"

|So my question is, when writing extensions, is the "old" way of defining the
|singleton method "new" deprecated? Are we to use the new allocate/initialize
|way now?

If you have chance to update the extension, use new allocation scheme
now. But the old scheme would work during 1.8.x series.

matz.
 
P

Paul Brannan

In 1.6, when writing an extension which required Data_Wrap_Struct, the
programmer would define the singleton method "new" to handle that. In 1.8, the
scheme seems to be to write an allocate function (to pass to
rb_define_alloc_func) then do the rest of the code in the intialize function.
Indeed, that's what Class#new does now.

So my question is, when writing extensions, is the "old" way of defining the
singleton method "new" deprecated? Are we to use the new allocate/initialize
way now?

You can do this on 1.6:

inline VALUE ruby_16_new(int argc, VALUE * argv, VALUE klass)
{
VALUE obj = rb_funcall(klass, rb_intern("allocate"), 0);
rb_obj_call_init(obj, argc, argv);
return obj;
}

rb_define_singleton_method(klass, "allocate", allocate_func, -1);
rb_define_singleton_method(klass, "new", ruby_16_new, -1);
rb_define_method(klass.v, "initialize", initialize_func, -1);

This allows you to divide your code into allocate/initialize similar to
how you would on 1.8.

Paul
 
E

Eric Hodel

--27ZtN5FSuKKSZcBU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Hello All,
=20
Has anyone got, or know of a diagram that shows how the ruby classes are
ordered in terms of inheritence?

Using ObjectSpace.each_object(Class) and a bit of code (like in the
attached script), you can generate one for yourself. Note that the
below does not mention any included modules (an exercise for the
reader).

Actually, the code I wrote could no doubt be compacted significantly,
any takers?

ruby 1.6.8 (2002-12-24) [i386-freebsd5]
Kernel
Object
Array
Binding
ClassNode
Continuation
Data
Dir
Exception
Interrupt
NoMemoryError
ScriptError
LoadError
NameError
NotImplementedError
SyntaxError
SignalException
StandardError
ArgumentError
IOError
EOFError
IndexError
LocalJumpError
RangeError
FloatDomainError
RegexpError
RuntimeError
SecurityError
SystemCallError
Errno::E2BIG
Errno::EACCES
Errno::EADDRINUSE
Errno::EADDRNOTAVAIL
Errno::EAFNOSUPPORT
Errno::EAGAIN
Errno::EALREADY
Errno::EBADF
Errno::EBUSY
Errno::ECHILD
Errno::ECONNABORTED
Errno::ECONNREFUSED
Errno::ECONNRESET
Errno::EDEADLK
Errno::EDESTADDRREQ
Errno::EDOM
Errno::EDQUOT
Errno::EEXIST
Errno::EFAULT
Errno::EFBIG
Errno::EHOSTDOWN
Errno::EHOSTUNREACH
Errno::EIDRM
Errno::EILSEQ
Errno::EINPROGRESS
Errno::EINTR
Errno::EINVAL
Errno::EIO
Errno::EISCONN
Errno::EISDIR
Errno::ELOOP
Errno::EMFILE
Errno::EMLINK
Errno::EMSGSIZE
Errno::ENAMETOOLONG
Errno::ENETDOWN
Errno::ENETRESET
Errno::ENETUNREACH
Errno::ENFILE
Errno::ENOBUFS
Errno::ENODEV
Errno::ENOENT
Errno::ENOEXEC
Errno::ENOLCK
Errno::ENOMEM
Errno::ENOMSG
Errno::ENOPROTOOPT
Errno::ENOSPC
Errno::ENOSYS
Errno::ENOTBLK
Errno::ENOTCONN
Errno::ENOTDIR
Errno::ENOTEMPTY
Errno::ENOTSOCK
Errno::ENOTTY
Errno::ENXIO
Errno::EOPNOTSUPP
Errno::EOVERFLOW
Errno::EPERM
Errno::EPFNOSUPPORT
Errno::EPIPE
Errno::EPROTONOSUPPORT
Errno::EPROTOTYPE
Errno::ERANGE
Errno::EREMOTE
Errno::EROFS
Errno::ESHUTDOWN
Errno::ESOCKTNOSUPPORT
Errno::ESPIPE
Errno::ESRCH
Errno::ESTALE
Errno::ETIMEDOUT
Errno::ETOOMANYREFS
Errno::ETXTBSY
Errno::EUSERS
Errno::EXDEV
SystemStackError
ThreadError
TypeError
ZeroDivisionError
SystemExit
fatal
FalseClass
File::Stat
Hash
IO
File
MatchData
Method
UnboundMethod
Module
Class
NilClass
Numeric
Float
Integer
Bignum
Fixnum
Proc
Range
Regexp
String
Struct
Struct::Tms
Symbol
Thread
ThreadGroup
Time
TrueClass

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--27ZtN5FSuKKSZcBU
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (FreeBSD)

iD8DBQE/qqWhMypVHHlsnwQRArniAKDbn00UJEiPcq0jICt2A1qlQFZZwwCdGKD3
HS0zRowIs75DSlY9gpY9Xy8=
=FNW+
-----END PGP SIGNATURE-----

--27ZtN5FSuKKSZcBU--
 
E

Eric Hodel

--jaTU8Y2VLE5tlY1O
Content-Type: multipart/mixed; boundary="4C6bbPZ6c/S1npyF"
Content-Disposition: inline


--4C6bbPZ6c/S1npyF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Thank you ever so much for that, but do you have the script? Only, It
wasn't attached to the e-mail :)

Dang, oops!

Here it is, no really.

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


--4C6bbPZ6c/S1npyF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="x.rb"
Content-Transfer-Encoding: quoted-printable

klasses =3D []

class ClassNode

@@nodes =3D {}

attr_accessor :val, :children

def initialize(val)
@Val =3D val
@children =3D []
end

def walk_children(level, &block)
block.call("#{' '*level}#{@val}\n")
level +=3D 1
children.sort { |a, b| a.name <=3D> b.name }.each do |child|
node =3D @@nodes[child]
unless node.nil? then
node.walk_children(level, &block)
else
block.call("#{' '*level}#{child}\n")
end
end
end

def self.add(node, parent)
if @@nodes.has_key? parent then
@@nodes[parent].children << node
else
@@nodes[parent] =3D ClassNode.new(parent)
@@nodes[parent].children << node
end
end

def self.tree(root =3D Kernel)
rv =3D ""

@@nodes[root].walk_children(0) do |s| rv << s end

return rv
end
end

ObjectSpace.each_object(Class) do |klass|
ancestor =3D nil
klass.ancestors[1..-1].each do |a|
if a.kind_of? Class or a =3D=3D Kernel then
ancestor =3D a=20
break
end
end

klasses << [klass, ancestor]
end

klasses.each do |klass, ancestor|
ClassNode.add(klass, ancestor)
end

puts ClassNode.tree


--4C6bbPZ6c/S1npyF--

--jaTU8Y2VLE5tlY1O
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (FreeBSD)

iD8DBQE/qr09MypVHHlsnwQRAiYDAJ49Tl/EqrHHyQNICJOl0Y12k+HjGACfUoQG
/73jLbSqO0q9O4qKQ8rCYjQ=
=jDhZ
-----END PGP SIGNATURE-----

--jaTU8Y2VLE5tlY1O--
 
K

KUBO Takehiro

Paul Brannan said:
You can do this on 1.6:

inline VALUE ruby_16_new(int argc, VALUE * argv, VALUE klass)
{
VALUE obj = rb_funcall(klass, rb_intern("allocate"), 0);
rb_obj_call_init(obj, argc, argv);
return obj;
}

rb_define_singleton_method(klass, "allocate", allocate_func, -1);
rb_define_singleton_method(klass, "new", ruby_16_new, -1);
rb_define_method(klass.v, "initialize", initialize_func, -1);

This allows you to divide your code into allocate/initialize similar to
how you would on 1.8.

Or you can do this on 1.6 and 1.8:

static VALUE foo_s_allocate(VALUE klass)
{
......
}

static VALUE foo_initialize(int argc, VALUE *argv, VALUE self)
{
......
}

#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
/* ruby 1.6 */
static VALUE foo_s_new(int argc, VALUE * argv, VALUE klass)
{
VALUE obj = foo_s_allocate(klass);
rb_obj_call_init(obj, argc, argv);
return obj;
}
#endif

void Init_foo()
{
....
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
/* ruby 1.8 */
rb_define_alloc_func(klass, foo_s_allocate);
#else
/* ruby 1.6 */
rb_define_singleton_method(klass, "new", foo_s_new, -1);
#endif
rb_define_method(klass, "initialize", foo_initialize, -1);
....
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top