develooper Front page | perl.perl6.language | Postings from March 2005

Re: some misc Perl 6 questions

Thread Previous | Thread Next
From:
Darren Duncan
Date:
March 8, 2005 22:29
Subject:
Re: some misc Perl 6 questions
Message ID:
p06210201be543dfca7ad@[192.168.1.102]
Thanks for your feedback Larry; much appreciated it is.

A few more interesting things happened since then, which can be seen 
in the current version of Locale::KeyedText in the Pugs version 
control.

At 5:35 PM -0800 3/8/05, Larry Wall wrote:
>: 8. Is it possible with a sub or method argument signiture to specify
>: that the arguments must have defined values?  Or are specced
>: non-optional arguments only guaranteed to have the correct container
>: passed to them?
>
>I think you can place that constraint on a formal parameter with
>
>     $arg of Any where { .defined }
>
>or some such.  The MMD engine will simply ignore that particular
>signature if the constraint isn't satisfied.

The biggest change is that, upon a re-reading Synopsis 12 (and 9) 
that was inspired by your above comment, I created some subtypes 
which I now use everywhere; the declarations and some examples of use 
are:

   subtype KeyName of Str where { $_.defined and $_ ne '' and $_ !~ m/\W/ }

   subtype KeyNameHash of Hash is shape(KeyName) of Str; # keys are of 
type KeyName, values of type Str

   subtype PkgName of Str where { $_.defined and $_ ne '' and $_ !~ 
m/<-[a-zA-Z0-9_:]>/ }

   subtype PkgNameArray of Array of PkgName;

...

   class Locale::KeyedText::Message {

     has KeyName $.msg_key; # str - the machine-readable key that 
uniquely identifies this message

     has KeyNameHash %.msg_vars; # hash (str,str) - named variables 
for messages, if any, go here

   method new( $class: KeyName $msg_key, KeyNameHash ?%msg_vars ) 
returns Locale::KeyedText::Message {
     my $message = $class.bless( {} );
     $message.msg_key = $msg_key;
     $message.msg_vars = %msg_vars; # copy list values
     return( $message );
   }

...

   class Locale::KeyedText::Translator {

     has PkgNameArray @.tmpl_set_nms; # array of str - list of 
Template module Set Names to search

     has PkgNameArray @.tmpl_mem_nms; # array of str - list of 
Template module Member Names to search

   method new( $class: PkgNameArray @set_names, PkgNameArray 
@member_names ) returns Locale::KeyedText::Translator {
     my $translator = $class.bless( {} );
     $translator.tmpl_set_nms = @set_names; # copy list values
     $translator.tmpl_mem_nms = @member_names; # copy list values
     return( $translator );
   }

...

By using subtypes in this way, I could remove a lot of explicit input 
checking code from my methods, which is great.  Also, the "where 
clause" is not being repeated for every argument or attribute or 
variable declaration.  (I like SQL domains for the same reasons.)

So how does that code sample look?  Anything that looks like invalid 
Perl 6.  Anything no one thought of doing before but that looks like 
a good idea?

A question: Would "has PkgNameArray @.tmpl_set_nms;" do what I 
expect, where the array as a whole is the sub-type, or would it make 
an array where each element is the sub-type?

>: 5. If I have a class property defined using "has Str %.foo;", and an
>: object of the class is named "$bar", then is it correct syntax to
>: refer to the property as a whole using "$bar.foo" and an element
>: using "$bar.foo{'abc'}"?
>
>Yes, except that "has" always declares instance attributes, not class
>attributes.  You'd want "our" or "my" instead.  But as long as you
>declare the name with %.foo, it'll generate the accessor.  However,
>it might be wiser to go ahead and wrap your own accessor around it
>that takes the subscripting out of the hands of the user, in case
>you want to change the representation from hash to something else.

I meant to say "attributes", sorry.

I have my own accessors, with different names, and don't expect 
anyone to use the autogenerated ones.  But I
made the attributes public for now so that one of my classes could 
access the attributes of one of my other ones directly; both of these 
are defined in the same file.

Maybe that's a bad idea, and if so I can change it.

New question: Is there a way to say that two classes have a 
privileged relationship, sort of like a marriage, such that each can 
see and/or change otherwise private attributes in objects of the 
other class, and yet the attribute list of each class is completely 
different from the other?  Neither of the two objects is a subclass 
of the other, nor fulfills a role defined by the other.

For example, say that there are two closely related classes, 
Container and Node, where conceptually a Container object is an 
environment in which Node objects live.  I would like to declare the 
attributes of both classes private from the viewpoint of all other 
classes, but I want Container and Node objects to be able to read or 
set each others' attributes directly as if they were public.  Both 
classes have their own set of methods that outside code can invoke 
directly, and each kind of object can be held by external code.

Also, does my request sound like something that would be reasonable 
to do, or a bad practice to avoid?

Thank you for all the hard work you have been doing.

-- Darren Duncan

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About