Nathan Wiger <[EMAIL PROTECTED]> writes:
> > I'm kind of curious to know what you think would happen with the
> > following. I've commented where I'm confident...
> >
> > interface Number;
> > sub TIESCALAR;
> > sub STORE;
> > sub FETCH;
> >
> > package integer implements Number; # I really like this notation
>
> Tangentially, yes, it is nice to read, but it prevents multiple
> interface specifications. "use interface" is more consistent.
It does?
package integer implements qw/Number Countable/;
Et viola.
>
> > sub TIESCALAR {...};
> > sub STORE {...};
> > sub FETCH {...};
> >
> > my Number $i; # Number is an interface, so just an assertion
> > my integer $n; # integer->TIESCALAR($n);
> > my non_tied $object;# Just an assertion
> > defined($n); # Should be false
>
> Yes. The only potential gotcha is if the user decides to do something
> Really Evil and stores a value as part of their TIESCALAR method. Then
> $n->FETCH will return that value and defined($n) will be true.
>
> However, this is not the purpose of tie, and I think an appropriate
> response is: Don't Do That. I agree with both you and Damian that TIE*
> should be called on declaration for consistency. If a person doesn't
> know how to use tie, well, that's not our problem. ;-)
>
> > $n = 5;
> > $i = $n;
> > $n = 10;
> > print $i;
> > $i = $object; # Assertion fails
>
> Assuming you've set up your C<use optimize> restrictions appropriately,
> then yes. The key is really what 'non_tied' is setup as. If this is a
> builtin type that optimizes itself to be a string object, then yes it
> will fail. However, if 'non_tied' is just a synonym for 'float' (for
> some odd reason) then the last line will be ok.
I think you're missing the point. What does 'print $i' print? What
happens if you do C<$n = $i>? Does $i 'remember' that the number that
got assigned to it is an integer? What is the mechanism for that? It
seems that there will need to be some pretty far reaching changes to
Perl if you want this to do the Right Thing. Assuming we know what the
Right Thing is.
>
> > > my int @b :64bit; # again, just an assertion
> >
> > Asserting what? That's not valid syntax at the moment.
>
> But it will be. :-) See RFC 279.
Ah. I'll marshall arguments there then.
>
> > > @c = @b; # empty list passed still
> > > @b = (1,2); # int->TIEARRAY(@a, '64bit'); @b->CLEAR(...);
> >
> > Hmm... I think this is somewhat ugly. Assuming that you want
> > C<my int @b> to imply C<UNIVERSAL::isa(all(@a), 'int')> then tying the
> > entire array seems a bit weird.
>
> Not necessarily. The key is: *how* would you implement the assertion
> check?
>
> If you use tie, then your int class STORE method can do something like
> this:
>
> package int;
> use base 'var';
> # take defaults from var class
> STORE {
> if ( self->isa($_[1]) ) {
> SUPER->STORE($_[0], $_[1]); # internally store
> } else {
> die "Bad data $_[1]" if ( $under_strict_types );
> }
> }
Having the programmer implement this assertion check (or not) is a
Very Bad Idea. Assuming we're expecting to get some compiler
optimization from this then things should be enforced rather more
robustly.
> > Er... You seem to be implying here that *all* classes should have TIE
> > methods. Which is not good.
>
> No, I wasn't trying to imply that, I'll clarify this point. TIE methods
> are still completely optional.
Okay. It's just that your example that I quoted and you cut out seems
to imply otherwise.
> > Err... Specifying which classes implement an interface in the
> > interface specification is Wrong Wrong Wrong.
>
> Yes, you're right,
Phew.
> > Can I just point out that nobody has yet proposed that you can attach
> > attributes to a package?
>
> Didn't Damian propose C<package Foo : interface> already? ;-)
Not in an RFC, no.
> > I'm not entirely sure what you're driving at here. I thought you were
> > arguing that *all* packages that created objects would use tie magic,
> > in which case the new attribute becomes unnecessary. And if you're not
> > proposing that then :tie is too general in the cases where the module
> > can only tie to specific variable types. I think you get better
> > granularity with interfaces, which are way more general than a special
> > new attribute.
>
> No, let me back up a little. The idea is to make it so that tied
> interfaces - which are really different beasts from OO interfaces
> altogether because of their purpose - should be more closely integrated
> into Perl 6. This would allow you to create custom, optimized,
> strongly-typed variables that would function just like builtins:
>
> my Matrix @a = ([1,2,3], [4,5,6]);
> my NISMap %map :passwd = read_passwd_file();
> my Apache::Session %session :transaction;
>
> However, this is not to overshadow OO interfaces, which are needed for
> functional methods, as you note.
>
> The :tie attribute is a poorly chosen name. The original name was
> :implicit, and was going to be attached to the TIE subs:
>
> package Demo;
> sub TIESCALAR : implicit { ... }
> sub TIEHASH : implicit { ... }
> sub TIEARRAY { ... }
>
> So in this example, a user can say:
>
> my Demo $x;
> my Demo %x;
> my Demo @x; # TIEARRAY not called
>
> However, after thinking about this, I decided this was not a worthwhile
> distinction. How often would you want this behavior? So I decided to
> attach the attribute to the package:
>
> package Demo : implicit;
>
> But that really didn't connote what was going on. So I changed it to:
>
> package Demo : autotie;
>
> But then decided the 'auto' was redundant. However, the more I think
> about it it appears that :autotie is perhaps the best name *if* we're
> going to have an attribute.
>
> However, I don't see why somebody would not want to be able to
> automatically tie something, or why this would be seen as bad. And
> that's why I mentioned that an attribute name was probably unnecessary.
> Make sense?
Not really, no. The issue here not so much that the user needs to have
the option to tie or not to tie, but that the compiler needs to be
told that this package implements something that can autotie. And, I
would argue, there *will* be cases when it's only meaningful to
implement semantics for tying, say, scalars. So, given that we need to
tell the *compiler* that this is an autotying package for a given set
of variable types, we need some syntax to do this. To my way of
thinking, overloading interface usage in this case is a good thing
because C<use implements 'Tie::Scalar'>, say also informs the compiler
that it should throw an error if the package doesn't implement the
appropriate Tie behaviour. If we make the autotie stuff into a package
attribute then we should probably do a C<use implements 'Tie::Scalar'>
anyway...
BTW, when you quote stuff, could you *please* supply rather more
context than you do. I find myself having to go back to the original
message to get the context for some of my comments that you're
responding to. (Could that sentence be *more* convoluted I wonder?)
--
Piers