On Tue, Mar 08, 2005 at 10:29:30PM -0800, Darren Duncan wrote:
: 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;

Those seem to by syntactically correct.  What they don't allow you to
distinguish is whether you're using the constraints for MMD pattern matching
or validation--the practical difference being that you want to give
good error feedback if you're doing validation, and you want to silently
fail if you're doing MMD, and let the default routine spit out error
messages.  I'm not sure how to solve that problem offhand.  Using
different subtypes for ordinary methods vs multi methods seems like
about twice as many subtypes as you need.  Hmm, perhaps it's just another
failure context dependency.  So you write

    subtype Foo of Bar where { .defined or fail "Undefined Foo" }

and then the ordinary method dispatch can report the error, while
the MMD can suppress it and keep going.

My other quibble is that you seem to be prone to stating things in the
negative for at least two of your three tests here:

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

and it seems to me that you could simplify all that to just

    subtype KeyName of Str where { m/^\w+$/ }

If that succeeds, you know it's defined and non-null.  You might argue that
the m/\W/ short-circuits, but I would counter-argue that failure is
supposed to be the exceptional case, and in every successful call you have
to scan the whole string anyway.  Plus it's just easier to understand.
And it lets you write the constraint without explicit reference to $_,
which I will admit was my first motivation in wanting to rewrite your
constraint.  The negatives and redundancies I only noticed later.

:   class Locale::KeyedText::Message {
: 
:     has KeyName $.msg_key; # str - the machine-readable key that 
: uniquely identifies this message

That's fine.

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

That's not.  As pointed out in another message want

    has %.msg_vars is KeyNameHash; # hash (str,str) - named variables 

or maybe just

    has Str %.msg_vars is shape(KeyName); # hash (str,str) - named variables 

and avoid cluttering up the symbol table.

:   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 );
:   }

I'd write

    return $message;

but that's just stylistic.  C<return> is actually a list operator (at
least syntactically), so the parens are optional.  But I personally
prefer to view return as more of a keyword than a function.

: ...
: 
:   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

Here too, I'd probably just write

    has PkgName @.tmpl_set_nms;
    has PkgName @.tmpl_mem_nms;

:   method new( $class: PkgNameArray @set_names, PkgNameArray 
: @member_names ) returns Locale::KeyedText::Translator {

    method new( $class: PkgName @set_names, PkgName @member_names )
        returns Locale::KeyedText::Translator {

or maybe even just

    method new( $class: @set_names, @member_names )
        returns Locale::KeyedText::Translator {

and rely on the assignment to do the validation.  (But having the type
names will work better under MMD.)

And yes, "trusts" bestows trust on another class.  I have no opinion
on its suitability for any particular task.  I'm just the language
designer--my job is to shoot you in the foot and make you think
you did it to yourself.  :-)

Larry

Reply via email to