From: Leopold Toetsch <[EMAIL PROTECTED]> Date: Wed, 25 Jan 2006 16:54:59 +0100
Bob Rogers wrote: > Sometime between r11268 (probably) and 11276, there was a change to > the way that initialization methods get called, regardless of whether > "__init" or a 'BUILD' property is used. If I do > > .local pmc foo, hash > .local int foo_class > foo_class = find_type "User::Foo" > foo = new foo_class, hash > > to construct the object, the build method gets ".param pmc hash" bound > to the hash, as happened in earlier versions, and it works. If I > instantiate the same class without a hash via a string constant: > > .local pmc foo > foo = new "User::Foo" > > then the build method sees self in the hash parameter, and dies. It's > not obvious to me how this is happening. Are these somehow getting > treated differently by the new argument passing code? TIA, I've added a test using __init with and w/o an argument and it works as expected (see t/pmc/objects.t - last one). Great; thanks. As the __init function is called with differing args, it has to have a signature: .sub __init :method .param pmc arg :optional I notice that using an :opt_flag here also works now; it didn't seem to before. You may or may not want to include the extra test (attached). It's of course debatable, if we should consider an argument as flattening by default and call init with a signature "vO%" or "vO@" where '%' and '@' denote flattening hash or array respectively. That would be closer to HLL semantics. On the other hand, the current implementation avoids repeated slurping and re-flattening when a series of related __init methods call each other -- which in turn allows them to communicate by modifying the hash/array, instead of just the object. So, if it ain't broke, don't fix it? (Your test is hard to follow and it takes a lot of time to dig through all the method calls) Very true; I produced it via C&P from my compiler output, and didn't want to invest the time to pretty it up without discussion. Ome remark: I don't see any advantage in using the BUILD property - just the opposite - it's the only builtin method call that can be given another name, it complicates the object creation code, well and it's for sure a lot slower then just using __init. I'm in favour of removing it. leo That would suit me. I wrote the code that generated that nearly a year ago; I probably ought to rewrite it to emit __init methods in any case. -- Bob
Index: t/pmc/objects.t =================================================================== --- t/pmc/objects.t (revision 11353) +++ t/pmc/objects.t (working copy) @@ -6,7 +6,7 @@ use warnings; use lib qw( . lib ../lib ../../lib ); use Test::More; -use Parrot::Test tests => 63; +use Parrot::Test tests => 64; =head1 NAME @@ -1952,5 +1952,40 @@ ok 1 ok 2 OUTPUT - - + +pir_output_is(<<'CODE', <<'OUTPUT', "init with and w/o arg, using :opt_flag"); +.sub 'main' :main + .local pmc cl, o, h, a + cl = newclass "Foo" + addattribute cl, "a" + o = new 'Foo' + a = getattribute o, "a" + print a + h = new .Hash + $P0 = new .PerlString + $P0 = "ok 2\n" + h['a'] = $P0 + $I0 = find_type 'Foo' + o = new $I0, h + a = getattribute o, "a" + print a +.end + +.namespace ["Foo"] +.sub __init :method + .param pmc args :optional + .param int args_p :opt_flag + unless args_p goto set_default + $P0 = args['a'] + setattribute self, 'a', $P0 + .return () + +set_default: + $P0 = new .PerlString + $P0 = "ok 1\n" + setattribute self, 'a', $P0 +.end +CODE +ok 1 +ok 2 +OUTPUT