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

Reply via email to