RFC - Interpolation of method calls
=head1 TITLE Interpolation of method calls =head1 VERSION Maintainer: Michael G Schwern <[EMAIL PROTECTED]> Date: 14 Sep 2000 Version:1 Mailing List: [EMAIL PROTECTED] =head1 ABSTRACT Method calls should interpolate in double-quoted strings, and similar locations. print "Today's weather will be $weather->temp degrees and sunny."; Would deparse to: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; =head1 DESCRIPTION =head2 The Current Problem With OO & Interpolation Object-oriented programming encourages data-hiding, and one of the most basic tool for this is the accessor method. For reasons which should be obvious, C<$obj->foo()> is usually better than C<$obj->{foo}>. However, there are several barriers to using an accessor method as simply as one does a hash lookup. Other RFCs deal with most of the current issues, but a basic one still remains. print "Today's weather will be $weather->temp degrees and sunny."; This does not DWIM. Instead of interpolating C<$weather->temp> as a method call, it comes out as C<$weather.'->temp'> and is usually followed immediately by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??" Most programmers learning OO Perl expect this to work and are surprised to find that it does not. Work arounds abound: # If I wanted printf(), I'd have written it in C. printf "Today's weather will be %d degrees and sunny.", $weather->temp; my $temp = $weather->temp; print "Today's weather will be $temp degrees and sunny."; print "Today's weather will be @{[$weather->temp]} degrees and sunny."; print "Today's weather will be ".$weather->temp." degrees and sunny."; None are as simple and as obvious as: print "Today's weather will be $weather->{temp} degrees and sunny."; and because of this users groan at having to use accessor methods and are often tempted to violate encapsulation for ease of use. =head2 Proposed Solution - Interpolate Methods Therefore, it is proposed that direct object method calls be interpolated inside double quoted strings and similar constructs. print "Today's weather will be $weather->temp degrees and sunny."; should parse out as: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; thus returning DWIMness to methods and strings and removing one barrier to accessor method's acceptance over hash lookups for objects. Methods will be run in scalar context. A method which returns a single scalar is treated normally. If a list is returned, it should be treated same as array interpolation. The list seperator will be applied. In effect, the deparsing will really work out as follows: print 'Today\'s weather will be '.join($", $weather->temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). (For the remainder of the RFC, the join() will be assumed when discussing deparsing for brevity.) Should it be decided that a formal distinction be made between accessor methods and other types (RFC 95), method interpolation should interpolate B method. =head2 Argument passing Interpolation should also handle passing arguments to methods in a string: print "Today's weather will be $weather->temp("F") degrees and sunny."; This should deparse to: print 'Today\'s weather will be '.$weather->temp("F"). ' degrees and sunny.'; The arguments to the method are considered as normal expressions, thus: print "There is $obj->foo(this => $yar, that => 2 + 2) in my head."; deparses as: print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; =head1 CAVEATS Indirect object syntax, being already ambiguous, cannot be easily be distinguished in a string from normal text and should not be interpolated. This is ok, since accessors are rarely called with indirect object syntax. Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this need be applied? What about inside regexes? And if so, left and/or right hand side? Normally, whitespace is allowed between tokens of a method call. $obj -> bar ("this"); and $obj->bar("this"); are equivalent. Whitespace between the object, '->', method name and opening paren should be disallowed when interpolated. This will avoid many ambiguous cases. Should the method not exist, Perl will throw an exception/die as usual. C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated. Also C<"$obj->method->{key}"> for the case where a method returns a reference. =head1 IMPLEMENTATION The behavor of the parser to check for embedded variables would have to be altered, namely the case where an embedded variable is being dereferenced. A case would be added to allow method calls as well as hash and array index dereferences. Otherwise, parsing should remain as normal. =head1 REFERENCES RFC 95 - Object Classes (proposes automatic a
Re: RFC - Interpolation of method calls
This topic is actually covered, albeit far less in-depth and lumped with an unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware. On Thu, Sep 14, 2000 at 03:57:41AM -0400, Michael G Schwern wrote: > Methods will be run in scalar context. A method which returns a single scalar > is treated normally. If a list is returned, it should be treated same as > array interpolation. The list seperator will be applied. In effect, the > deparsing will really work out as follows: > > print 'Today\'s weather will be '.join($", $weather->temp()). > ' degrees and sunny.'; > > However if temp() calls wantarray(), the result will be FALSE (scalar). Ok, this is very confusing. You're saying the method is called in scalar context, but then proceed to call it in list context, meanwhile tricking it into thinking it's scalar context. Interpolated method calls should behave the same as every other method call, without extra magic. The only decision, then, is to decide which context to use; if it deparses to concatenation then it seems logical to use scalar context. This also makes sense in that you can force list context with @{[ $weather->temp ]} if you really wanted it. > =head2 Argument passing > > Interpolation should also handle passing arguments to methods in a string: > > print "Today's weather will be $weather->temp("F") degrees and sunny."; > > This should deparse to: > > print 'Today\'s weather will be '.$weather->temp("F"). > ' degrees and sunny.'; > > The arguments to the method are considered as normal expressions, thus: > > print "There is $obj->foo(this => $yar, that => 2 + 2) in my head."; > > deparses as: > > print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; Now perl is parsing full statements within strings. I -really- don't like this, not only because perl is now reaching into strings to parse yet more, but also because it's already beginning to look very difficult for me, personally, to parse. Not only that, it gives me the heeby-geebies (which of course means you should all immediately agree with me :). I'd say keep it simple, allow only simple, non-parenthetical method calls. "foo $foo->bar bar" --> "foo " . $foo->bar . " bar" "foo $foo->bar() bar" --> "foo " . $foo->bar . "() bar" Granted, it may confuse the newbies, but I think it makes things much easier on everyone. > Normally, whitespace is allowed between tokens of a method call. > > $obj -> bar ("this"); > > and > > $obj->bar("this"); > > are equivalent. Whitespace between the object, '->', method name and opening > paren should be disallowed when interpolated. This will avoid many ambiguous > cases. This is a good idea, and has precedence (as I just discovered answering someone's question about it in #Perl as I was writing this email, weird..): "$hash -> {'foo'}" --> "HASH(0x8bbf0b8) -> {k1}" Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: Draft RFC: new pragma: C
I would suggest that anyone want to contribute to this discussion should first read the thread about the addition of this pragma to perl5 in the perl5-porters archives http://www.xray.mpe.mpg.de/cgi-bin/w3glimpse/perl5-porters?query=use+namespace+pragma&errors=0&case=on&maxfiles=100&maxlines=30 Graham.
Re: Draft RFC: new pragma: C
Graham Barr <[EMAIL PROTECTED]> writes: > I would suggest that anyone want to contribute to this discussion should > first read the thread about the addition of this pragma to perl5 in > the perl5-porters archives > > >http://www.xray.mpe.mpg.de/cgi-bin/w3glimpse/perl5-porters?query=use+namespace+pragma&errors=0&case=on&maxfiles=100&maxlines=30 Ah. Sorry I didn't post that url with the RFC. -- Piers
Re: RFC 218 (v1) C is just an assertion
Perl6 RFC Librarian <[EMAIL PROTECTED]> writes: > This and other RFCs are available on the web at > http://dev.perl.org/rfc/ > > =head1 TITLE > > C is just an assertion > > =head1 VERSION > > Maintainer: Piers Cawley <[EMAIL PROTECTED]> > Date: 13th September 2000 > Mailing List: [EMAIL PROTECTED] > Number: 218 > Version: 1 > Status: Developing > > =head1 ABSTRACT > > The behaviour of the syntax should simply be an > assertion of the invariant: > >(!defined($spot) || (ref($spot) && $spot->isa('Dog))) > > =head1 DESCRIPTION > > The syntax > > my Dog $spot = Dog->new(); > > currently carries little weight with Perl, often failing to do what > one expects: > > $ perl -wle 'my Dog::$spot; print "ok"' > No such class Dog at -e line 1, near "my Dog" > Execution of -e aborted due to compilation errors. > $ perl -wle 'sub Dog::new; my Dog $spot; print "ok"' > ok > $ perl -wle 'sub Dog::new; my Dog $spot = 1' > ok > > The first example is obvious, as is the second. The third one is > I. Actually, it's *very* weird given that there's no code to print 'ok'. Which is bad. $ perl -wle 'sub Dog::new; my Dog $spot = 1; print "ok"' That's better. -- Piers
Re: RFC 218 (v1) C is just an assertion
Nathan Torkington <[EMAIL PROTECTED]> writes: > Perl6 RFC Librarian writes: > > I therefore propose that C comes to mean that C<$spot> > > is restricted to being either undefined or a reference to a C > > object (or any subclasses of Dog). Simply having this implicit > > assertion can be useful to the programmer, but I would argue that its > > main advantage is that the compiler knows the object's interface at > > compile time and can potentially use this fact to speed up method > > dispatch. > > Yes! I mentioned the hypothetical > use strict 'types'; > which would require all variables assigned to/from an object, and > all variables upon which method calls are made, to be typed like > this. Then the compiler can: > (a) optimize > (b) check at compile-time > > Your sample implementation is done through a Tie class, which is only > runtime. The big win is that if you check types like this (and it's > a window into C's type-checking hell) then Perl knows types at > compile-time. If there's a formal interface specification for classes, > the compiler can use this to check whether a method call is valid or > not. You can build calls to the correct subroutine into optree > instead of delaying that lookup until runtime. > > Every compile-time check comes at the cost of a run-time freedom, > though. All bets would be off if you modified @ISA, reblessed, or > passed objects through non-strict-types-compliant code. Polymorphic > types also becomes a problem: how to say that it's okay for a variable > to hold a Dog *or* a Cat, because we know that both of them have a > "pet()" method? > > I'd love to see these suggestions incorporated into your RFC. I was > going to do it myself, but I have a lot of other things to RFC. TBH, I'm not sure I want to go too far down that road in this RFC. And tbh they seem more like internals issues to me. The runtime behaviour this change grants is good enough for me and I don't want to see the proposal bogged down in flamage about strict types. Of course, given this RFC it's possible to add other RFCs that deal with specific dependent language proposals and optimizations. > > =head1 MIGRATION > > > > Migration issues should be minor, the only problem arising when people > > have assigned things that aren't objects of the appropriate type to > > typed variables, but they deserve to lose anyway. > > Not if you made the checks and optimizations enabled by a pragma. > Old programs wouldn't have it, so they could continue to do their > stupid things and be fine. Again, I'm not sure that I'd want to encourage such bogosity. After all, if perl5 could introduce "@array" interpolation which broke stuff I don't see why this one can't go through as the default. -- Piers
Re: RFC 218 (v1) C is just an assertion
Nathan Wiger <[EMAIL PROTECTED]> writes: > Nathan Torkington wrote: > > > > Yes! I mentioned the hypothetical > > use strict 'types'; > > which would require all variables assigned to/from an object, and > > all variables upon which method calls are made, to be typed like > > this. Then the compiler can: > > (a) optimize > > (b) check at compile-time > > Hate to add a "me too", but I think this is a great idea. Nat needs to > be able to torture himself in whatever sick C-type ways he desires. ;-) > ;-) > > Seriously, though, this adds lots of potential benefits. > > > Polymorphic > > types also becomes a problem: how to say that it's okay for a variable > > to hold a Dog *or* a Cat, because we know that both of them have a > > "pet()" method? > > Seems in order to satisfy this you'd have to have a common ancestor, > Pet, which Dog and Cat inherited: > >my Pet $foofoo; # Can be Dog, Cat, or anything inherited I'm kind of tempted to look at adding another pragma to go with 'use base' along the lines of: use implements 'Interface'; Which is almost entirely like C but with 'Interface' consisting of nothing but: package Interface; sub virtual_method; sub virtual_method2 (#prototype); ... 1; This is, of course, strictly unnecessary since C could do exactly the same thing, and it is painfully Javalike. It kind of depends on whether or not useful compiletime optimizations become possible if a class is flagged as being 'virtual'. > And if you didn't want inherited classes to count, you could specify > that as an attribute: > >my Pet $foofoo : onlybase;# Must be a Pet, not Cat/Dog > > Or ":only", ":nochildren", ":justme", or any other similar word... Why on earth would I want to do that? You just shot the polymorphism in the head. -- Piers
Re: RFC 218 (v1) C is just an assertion
Michael G Schwern <[EMAIL PROTECTED]> writes: > On Wed, Sep 13, 2000 at 08:43:43PM -, Perl6 RFC Librarian wrote: > > The behaviour of the syntax should simply be an > > assertion of the invariant: > > > >(!defined($spot) || (ref($spot) && $spot->isa('Dog))) > > What about the current behavior of typed pseudohashes? > > package Dog; > use fields qw(this night up); > > my Dog $ph = []; > $ph->{this} = "that"; That works? I thought you had to do: my Dog $self = fields::new('Dog'); (In which case, as far as I can see, the proposal makes no difference.) -- Piers
Re: RFC - Interpolation of method calls
> This topic is actually covered, albeit far less in-depth and lumped with an > unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware. Yeah, I've got to split those up. I was trying cut down on the flood of RFC's that poor Larry has to sift through :-(, but they are both complex issues. Schwern, if you want to take this one over, it's all yours. There has already been some discussion on this here: http://www.mail-archive.com/perl6-language@perl.org/msg02169.html I would encourage people to read the thread. In particular, to be truly consistent we should interpolate class as well as instance methods, i.e.: "Hello, Class->name"; But there's a lot of problems with this and I'm not sure it's a good idea. > > print 'Today\'s weather will be '.join($", $weather->temp()). > > ' degrees and sunny.'; > > > > However if temp() calls wantarray(), the result will be FALSE (scalar). > > Ok, this is very confusing. I think what he's trying to get at is that these should all work the same: print "Here's some @stuff"; print "Here's some $h->{stuff}"; print "Here's some $r->stuff"; > > print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; > > Now perl is parsing full statements within strings. This already happens with: print "Here's some $h->{$stuff}"; print "Here's some $a->[$stuff + $MIN]"; So it's not that confusing, and quite consistent. > I'd say keep it simple, allow only simple, non-parenthetical method calls. No, this makes it impossible to do this: print "Your name is $cgi->param('name')"; And it's also inconsistent with how hashrefs and arrayrefs work already. -Nate
Re: Draft RFC: new pragma: C
Nathan Wiger wrote: > > > use namespace 'Big::Long::Prefix'; > > my ::Class $object = ::Class->new; > > Assuming repairing :: precedence is a reality I don't think this > proposal buys us anything. ...That being said, I'm not necessarily against it. I'm just against bloat. I hadn't paid too much attention to the actual patch the first time reading it through, but it looks like a simple thing to add. And the one nice thing it does add is that these: $::stuff $main::stuff don't always mean the same thing, which at least gives some real reason for having the first version around. If this change is made, though, then I think it should work the same way in packages: package Foo; $::bar = "stuff"; # $Foo::bar = "stuff" For consistency. That way the rule is: "If no prefix is found to ::, then the current package namespace is used. You can change the current namespace either via 'package' (if you want to encapsulate a new package), or 'use namespace' (if you simply want a shortcut way of referring to variables)". This might have been discussed, but I didn't see it in the threads (I could have missed it, though). For anyone looking for a direct link to the start of the patch thread: http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-07/msg00490.html -Nate
Re: RFC - Interpolation of method calls
Michael G Schwern <[EMAIL PROTECTED]> writes: > >print "Today's weather will be $weather->temp degrees and sunny."; > >This does not DWIM. Instead of interpolating C<$weather->temp> as a method >call, it comes out as C<$weather.'->temp'> and is usually followed immediately >by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??" Most >programmers learning OO Perl expect this to work and are surprised to find >that it does not. I think $-> is unlikely enough in a string that this is worth considering. > >Work arounds abound: print $weather->report; being the one I like best - avoids the un-meritted assumption it will be sunny ;-) -- Nick Ing-Simmons <[EMAIL PROTECTED]> Via, but not speaking for: Texas Instruments Ltd.
Re: RFC 218 (v1) C is just an assertion
Piers Cawley writes: > TBH, I'm not sure I want to go too far down that road in this RFC. And > tbh they seem more like internals issues to me. The runtime behaviour > this change grants is good enough for me and I don't want to see the > proposal bogged down in flamage about strict types. Of course, given > this RFC it's possible to add other RFCs that deal with specific > dependent language proposals and optimizations. Ok, I'll work on the RFC for the type-checking. Nat
Re: RFC - Interpolation of method calls
On Thu, Sep 14, 2000 at 07:49:32AM -0700, Nathan Wiger wrote: > > > print 'Today\'s weather will be '.join($", $weather->temp()). > > > ' degrees and sunny.'; > > > > > > However if temp() calls wantarray(), the result will be FALSE (scalar). > > I think what he's trying to get at is that these should all work the > same: > >print "Here's some @stuff"; >print "Here's some $h->{stuff}"; >print "Here's some $r->stuff"; That may be, but I don't think calling it in one context, accepting another, and lying about it all is the right way to go. I think I'll let the author try to explain what he had intended. > > > print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; > > > > Now perl is parsing full statements within strings. > > This already happens with: > >print "Here's some $h->{$stuff}"; >print "Here's some $a->[$stuff + $MIN]"; > > So it's not that confusing, and quite consistent. Well, I still find it confusing (most probably because of the length of the examples), but it is indeed consistent. Stupid mistake on my part. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
RFC 49 (v3) Objects should have builtin stringifying STRING method
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Objects should have builtin stringifying STRING method =head1 VERSION Maintainer: Nathan Wiger <[EMAIL PROTECTED]> Date: 06 Aug 2000 Last Modified: 14 Sep 2000 Mailing List: [EMAIL PROTECTED] Number: 49 Version: 3 Status: Frozen =head1 ABSTRACT Currently, $ single-whatzitz types in Perl can hold several different things. One of the things that these are commonly used to hold are objects, such as: $q = new CGI; $r = Apache->request; Unfortunately, there is no easy way to tell these are actually objects without lots of annoying ref checks throughout your code. So if you say: print "$q"; This prints out something like this: CGI=HASH(0x80ba4e8) Which isn't very useful. This RFC attempts to fix this by providing builtin special method C which is automatically called when an object is "stringified". While this can be accomplished through the use of 'use overload', a more automatic, object-specific method has certain advantages. For more details on this, please see RFC 159. =head1 NOTES ON FREEZE This RFC goes into details on the uses of C, but what you really want to read is L, which extends these concepts to other Perl operators and contexts. =head1 DESCRIPTION Currently, there is no way to easily distinguish between these two syntaxes: $scalar = date; # scalar ctime date, same as localtime() $object = date; # date object with accessor functions As such, there is no easy way to have the C function return both - it must decide what to return within the general scalar context. Damian's excellent RFC 21 on C addresses several specific cases, several have suggested alternate syntaxes, such as: my Date $object = date; # return object of class 'Date' my tm $object = date; # return object of struct 'tm' However, this doesn't solve the problem, since printing out either of these in a scalar context still results in "garbage". I suggest that objects provide a default method called C that determines what they produce in a string context. When stringified, an object would automatically call its C function and return the correct value. For example, RFC 48 describes a new C interface. In a scalar context, it could produce a date object always: $date = date; However, when you went to do anything with it in a string context, it would call the appropriate method: print "$date"; # calls $date->STRING, which in this case would # print out a ctime formatted date string The call to C<$object->STRING> would be a decision made by Perl, similar to the way that C works. The object simply has to provide the method; Perl does the rest. This gives us several other really neat side effects. First, we can now return a list of objects and have them act the same as a "regular old list": (@objects) = Class->new; Since, in a stringifying context, each of these objects would call their C methods: print "@objects"; # calls $objects[0]->STRING, $objects[1]->STRING, # and so on for the whole array, thus making it # look like a plain old list As such, we no longer have to distinguish between objects and "true" scalars. Objects are automatically converted when appropriate. =head1 IMPLEMENTATION All core objects should be modified to include a C function. This function may just be a typeglob pointing to another function, or it may be an actual separate function. Hooks will have to be put in Perl's string context so that if something is an object, then that object's C method is called automatically if it exists. =head1 MIGRATION None. This introduces new functionality. =head1 REFERENCES RFC 159: True Polymorphic Objects RFC 21: Replace wantarray with a generic want function RFC 48: Replace localtime() and gmtime() with date() and utcdate() Lots of people on perl6-language for great input, thanks!
Re: RFC 218 (v1) C is just an assertion
On Thu, Sep 14, 2000 at 02:19:38PM +0100, Piers Cawley wrote: > Michael G Schwern <[EMAIL PROTECTED]> writes: > > package Dog; > > use fields qw(this night up); > > > > my Dog $ph = []; > > $ph->{this} = "that"; > > That works? I thought you had to do: > > my Dog $self = fields::new('Dog'); Nope. fields::new() basically just does C, but the current pseudohash implementation doesn't care if something is an object or not. It just cares about either A) its type or B) what's in $ph->[0]. I don't know if this is a good thing or a bad thing, but there's nothing on the table to change it (yet). my Dog $ph = []; $ph->{this} = "that"; deparses at compile-time to: my Dog $ph = []; $ph->[$Dog::FIELDS{this}] = "that"; # actually the %FIELDS lookup is also # done at compile time, but I left # it in for illustration. -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Sometimes these hairstyles are exaggerated beyond the laws of physics - Unknown narrator speaking about Anime
RFC 222 (v1) Interpolation of method calls
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Interpolation of method calls =head1 VERSION Maintainer: Michael G Schwern <[EMAIL PROTECTED]> Date: 14 Sep 2000 Mailing List: [EMAIL PROTECTED] Number: 222 Version: 1 Status: Developing =head1 ABSTRACT Method calls should interpolate in double-quoted strings, and similar locations. print "Today's weather will be $weather->temp degrees and sunny."; Would deparse to: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; =head1 DESCRIPTION =head2 The Current Problem With OO & Interpolation Object-oriented programming encourages data-hiding, and one of the most basic tool for this is the accessor method. For reasons which should be obvious, C<$obj->foo()> is usually better than C<$obj->{foo}>. However, there are several barriers to using an accessor method as simply as one does a hash lookup. Other RFCs deal with most of the current issues, but a basic one still remains. print "Today's weather will be $weather->temp degrees and sunny."; This does not DWIM. Instead of interpolating C<$weather->temp> as a method call, it comes out as C<$weather.'->temp'> and is usually followed immediately by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??" Most programmers learning OO Perl expect this to work and are surprised to find that it does not. Work arounds abound: # If I wanted printf(), I'd have written it in C. printf "Today's weather will be %d degrees and sunny.", $weather->temp; my $temp = $weather->temp; print "Today's weather will be $temp degrees and sunny."; print "Today's weather will be @{[$weather->temp]} degrees and sunny."; print "Today's weather will be ".$weather->temp." degrees and sunny."; None are as simple and as obvious as: print "Today's weather will be $weather->{temp} degrees and sunny."; and because of this users groan at having to use accessor methods and are often tempted to violate encapsulation for ease of use. =head2 Proposed Solution - Interpolate Methods Therefore, it is proposed that direct object method calls be interpolated inside double quoted strings and similar constructs. print "Today's weather will be $weather->temp degrees and sunny."; should parse out as: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; thus returning DWIMness to methods and strings and removing one barrier to accessor method's acceptance over hash lookups for objects. Methods will be run in scalar context. A method which returns a single scalar is treated normally. If a list is returned, it should be treated same as array interpolation. The list seperator will be applied. In effect, the deparsing will really work out as follows: print 'Today\'s weather will be '.join($", $weather->temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). (For the remainder of the RFC, the join() will be assumed when discussing deparsing for brevity.) Should it be decided that a formal distinction be made between accessor methods and other types (RFC 95), method interpolation should interpolate B method. =head2 Argument passing Interpolation should also handle passing arguments to methods in a string: print "Today's weather will be $weather->temp("F") degrees and sunny."; This should deparse to: print 'Today\'s weather will be '.$weather->temp("F"). ' degrees and sunny.'; The arguments to the method are considered as normal expressions, thus: print "There is $obj->foo(this => $yar, that => 2 + 2) in my head."; deparses as: print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; =head1 CAVEATS Indirect object syntax, being already ambiguous, cannot be easily be distinguished in a string from normal text and should not be interpolated. This is ok, since accessors are rarely called with indirect object syntax. Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this need be applied? What about inside regexes? And if so, left and/or right hand side? Normally, whitespace is allowed between tokens of a method call. $obj -> bar ("this"); and $obj->bar("this"); are equivalent. Whitespace between the object, '->', method name and opening paren should be disallowed when interpolated. This will avoid many ambiguous cases. Should the method not exist, Perl will throw an exception/die as usual. C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated. Also C<"$obj->method->{key}"> for the case where a method returns a reference. =head1 IMPLEMENTATION The behavor of the parser to check for embedded variables would have to be altered, namely the case where an embedded variable is being dereferenced. A case would be added to allow method calls as well as hash and array index dereferences. Otherwise, pars
Re: RFC 222 (v1) Interpolation of method calls
First of all, I think this is a great idea On 14 Sep 2000, Perl6 RFC Librarian wrote: > Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this > need be applied? What about inside regexes? And if so, left and/or right > hand side? Regexes are enough like double quoted strings that I think _not_ interpolating here would be confusing. The same goes for backticks (`)/qx, which is double-quote interpolated as well. -dave /*== www.urth.org We await the New Sun ==*/
RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Objects : Hierarchical calls to initializers and destructors =head1 VERSION Maintainer: Damian Conway <[EMAIL PROTECTED]> Date: 1 September 2000 Mailing List: [EMAIL PROTECTED] Number: 189 Version: 2 Status: Developing =head1 ABSTRACT This RFC proposes a new special method called C that is invoked automagically whenever an object is created. Furthermore, it proposes that both C and C methods should be invoked hierarchically in all base classes. =head1 DESCRIPTION One of the major limitations of object-oriented Perl is that, unlike most other OO languages, it does not automatically invoke the initializers and destructors of base classes, when initializing or destructing an object of a derived class. This leads to tediously complex code in constructors and destructors in order to manually achieve the same effect. More often, it leads to bugs. It is proposed that Perl 6 introduce an automatic object initialization mechanism, analogous to the automatic object clean-up mechanism provided by C methods. It is further proposed that both the initialization and destruction mechanisms automatically call their corresponding base class versions to ensure that complete initialization and destruction of derived objects occurs correctly. =head2 The C method It is proposed that, if a class has a method named C, that method will be invoked automatically during any call to C. It is further proposed that C be extended to take an optional argument list after its second argument, and that this list would be passed to any C method invoked by the C. The typical constructor would then be reduced to: package MyClass; sub new { bless {}, @_ } with initialization handled in a separate C routine: sub BUILD { my ($self, @ctor_data) = @_; # initialization of object referred to by $self occurs here } =head2 Hierarchical C calls It is proposed that when an object is blessed, I of the C methods in any of its base classes are also called, and passed the argument list appended to the invocation of C. C methods would be called in depth-first, left-most order (i.e. ancestral C methods would be called before derived ones). Any given C method would only be called once for the same object, no matter how many separate paths its class might be inherited through. For example, given the following class hierarchy: package Base1; sub new { bless {}, @_ } sub BUILD { print "Base1::BUILD : @_\n" } package Base2; sub BUILD { print "Base2::BUILD : @_\n" } package Base3; sub BUILD { print "Base3::BUILD : @_\n" } package Derived1; use base qw(Base1 Base2); sub BUILD { print "Derived1::BUILD : @_\n" } package Derived2; use base qw(Base2 Base3); sub BUILD { print "Derived2::BUILD : @_\n" } package Rederived1; use base qw(Derived1 Derived2); sub BUILD { print "Rederived1::BUILD : @_\n" } then the call to: $obj = Rederived->new(1..3) would print: Base1::BUILD : 1 2 3 Base2::BUILD : 1 2 3 Derived1::BUILD : 1 2 3 Base3::BUILD : 1 2 3 Derived2::BUILD : 1 2 3 Rederived1::BUILD : 1 2 3 Note in particular that C is only called once (as early as possible), even though class Rederived inherits it through two distinct paths. =head2 Hierarchical C calls It is further proposed that when an object's destructor is invoked, all inherited destructors would also be invoked, in depth-I, right-most order. Again, each C for an object would be called exactly once, regardless of how many different paths it is inherited through. For example, given the following class hierarchy (with the same topology as the example for C above): package Base1; sub new { bless {}, @_ } sub DESTROY { print "Base1::DESTROY\n" } package Base2; sub DESTROY { print "Base2::DESTROY\n" } package Base3; sub DESTROY { print "Base3::DESTROY\n" } package Derived1; use base qw(Base1 Base2); sub DESTROY { print "Derived1::DESTROY\n" } package Derived2; use base qw(Base2 Base3); sub DESTROY { print "Derived2::DESTROY\n" } package Rederived1; use base qw(Derived1 Derived2); sub DESTROY { print "Rederived1::DESTROY\n" } then the destruction of an object: $obj = "something else"; would print: Rederived1::DESTROY Derived2::DESTROY Base3::DESTROY Derived1::DESTROY Base2::DESTROY Base1::DESTROY Note that C is only called once (as late as possible), even though class Rederived inherits it through two distinct paths. Note too that the C invocation sequence is the exact reverse of
RFC 224 (v1) Objects : Rationalizing C, C, and C
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Objects : Rationalizing C, C, and C =head1 VERSION Maintainer: Damian Conway <[EMAIL PROTECTED]> Date: 14 September 2000 Mailing List: [EMAIL PROTECTED] Number: 224 Version: 1 Status: Developing =head1 ABSTRACT This RFC proposes that rather than three separate mechanisms (in three separate namespaces) to determine object typing information, Perl 6 simply extend the C function to return all the necessary information in a list context. =head1 DESCRIPTION In Perl 5, the class into which an object is blessed is returned by calling C on a reference to that object. To determine the underlying implementation type of the object, C is used. To determine whether or not a reference refers to a blessed object, is used. It is proposed that the behaviour of C be altered in Perl 6 so that in a list context it returns up to two values: the underlying implementation type of the object (always returned), and the class into which the object is blessed (only if the object I blessed). Thus: if (builtin::blessed $ref) { $type = attribute::reftype $ref; $class = ref $ref; } else { $type = ref $ref; $class = ""; } print "Object of type $type, blessed into $class\n"; Would become: ($type, $class) = ref($ref); $class ||= ""; print "Object of type $type, blessed into $class\n"; =head1 MIGRATION ISSUES All existing calls to C in a list context would have to be translated to C. =head1 IMPLEMENTATION Trivial. =head1 REFERENCES None.
Re: RFC 218 (v1) C is just an assertion
Piers wrote: > I'm kind of tempted to look at adding another pragma to go with 'use > base' along the lines of: > > use implements 'Interface'; > > Which is almost entirely like C but with > 'Interface' consisting of nothing but: > > > package Interface; > > sub virtual_method; > sub virtual_method2 (#prototype); > > ... > > 1; You and I must have been separated at birth, Piers. Here's what I wrote to Nat just yesterday: There would be an C pragma or keyword (let's go with keyword) that creates pseudo-packages with which lexicals can be typed. interface Fetcher; sub fetch; Interface specifications can only contain subroutine (method) declarations, which describe what behaviours the interface requires. Lexicals typed into interfaces (as opposed to packages) only require that the objects assigned to them can satisfy the interface. I.e. they don't care about the class of the object, only what is C do. my Fetcher $x; my Dog $spot; my NetSnarfer $z; $x = $z;# ok because $z can fetch $x = $spot; # ok because $spot can fetch $x->fetch();# ok because Fetcher->can('fetch') $x->bark(); # not ok because ! Fetcher->can('bark') Interfaces might also act like pure abstract base classes when inherited, so that: package Dog; use base 'Fetcher'; would cause a compile-time error if Dog failed to actually provide a C method. If you'd like to run with it, be my guest (but check with Nat first, in case he wants it). Damian
Re: RFC 218 (v1) C is just an assertion
At 08:13 AM 9/15/00 +1100, Damian Conway wrote: >Piers wrote: > >> I'm kind of tempted to look at adding another pragma to go with 'use >> base' along the lines of: >> >> use implements 'Interface'; >> >> Which is almost entirely like C but with >> 'Interface' consisting of nothing but: >> >> >> package Interface; >> >> sub virtual_method; >> sub virtual_method2 (#prototype); >> >> ... >> >> 1; > >You and I must have been separated at birth, Piers. > >Here's what I wrote to Nat just yesterday: > > Interfaces might also act like pure abstract base classes when > inherited, so that: > > package Dog; > use base 'Fetcher'; > > would cause a compile-time error if Dog failed to actually provide > a C method. I don't like that at all... Currently, Object implementations can be changed at will at runtime. In particular, it is possible to create new methods and change the class hierarchy at run time. package TextFilter; use CryptInterface; @ISA = qw(CryptInterface); sub AUTOLOAD { my $self = shift; ($name = $AUTOLOAD) =~ s/.*://; # Cryptography is very hairy and we don't want to load it if we don't # have to. if ($name = any(qw(setkey setcrypt encode decode)) { require Crypt; import Crypt; push @ISA,"Crypt"; $self->$name(@_); # I've not tried this, it may be wrong. } } I'd hate to have that break because TextFilter isn't derived from Crypt unless it needs to be. I think calling a method declared in an inherited interface but not implemented would be a good reason to have a descriptive run-time error, like: Method getkey in interface Crypt not implemented in TextFilter object at line Well, perhaps written better... >If you'd like to run with it, be my guest (but check with Nat first, in >case he wants it). > >Damian
Re: RFC 222 (v1) Interpolation of method calls
> > Method calls should interpolate in double-quoted strings, and similar > locations. > > print "Today's weather will be $weather->temp degrees and sunny."; A possibility that does not appear in RFC222.1 is to put tho whole accessor expression inside curlies: print "Today's weather will be ${weather->temp} degrees and sunny."; which would follow the "You want something funny in your interpolated scalar's name or reference, you put it in curlies" rule. Since the contents of that expression is not strictly \w+ it does not get interpreted as the symbol table lookup ${'weather->temp'}, so that is not a problem, nor are the whitespace situations listed in the CAVEATS section. -- David Nicol 816.235.1187 [EMAIL PROTECTED] perl -e'map{sleep print$w[rand@w]}@w=<>' ~/nsmail/Inbox
Re: RFC 222 (v1) Interpolation of method calls
On Thu, Sep 14, 2000 at 06:37:22PM -0500, David L. Nicol wrote: > A possibility that does not appear in RFC222.1 is to put tho whole > accessor expression inside curlies: > > print "Today's weather will be ${weather->temp} degrees and sunny."; > > which would follow the "You want something funny in your interpolated > scalar's name or reference, you put it in curlies" rule. Since the contents > of that expression is not strictly \w+ it does not get interpreted as > the symbol table lookup ${'weather->temp'}, so that is not a problem, nor > are the whitespace situations listed in the CAVEATS section. Currently, ${weather->temp} means dereference the return value of the method 'temp' in the 'weather' class as a scalar reference (or a symbolic reference, if it's not a scalar reference and you're not using strict). Do you intend for this meaning to be taken away entirely, or to be special-cased within interpolated strings? If either I would have to heartily disagree with you; it's inconsistent, and while special cases can be a good thing when it comes to DWIM, I think we should DWIM on the side of interpolating method calls, rather than taking away existing syntax. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors
> =head2 The C method > =head3 The C method Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS that we all like! :-( -Nate
Re: RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors
> > =head2 The C method > > =head3 The C method > > Hey! You left out the alternative names NEW / RENEW and BLESS / REBLESS > that we all like! :-( Oops. You're correct. I will rectify that. Damian
RFC 222 (v1) Interpolation of method calls
This and other RFCs are available on the web at http://dev.perl.org/rfc/ =head1 TITLE Interpolation of method calls =head1 VERSION Maintainer: Michael G Schwern <[EMAIL PROTECTED]> Date: 14 Sep 2000 Mailing List: [EMAIL PROTECTED] Number: 222 Version: 1 Status: Developing =head1 ABSTRACT Method calls should interpolate in double-quoted strings, and similar locations. print "Today's weather will be $weather->temp degrees and sunny."; Would deparse to: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; =head1 DESCRIPTION =head2 The Current Problem With OO & Interpolation Object-oriented programming encourages data-hiding, and one of the most basic tool for this is the accessor method. For reasons which should be obvious, C<$obj->foo()> is usually better than C<$obj->{foo}>. However, there are several barriers to using an accessor method as simply as one does a hash lookup. Other RFCs deal with most of the current issues, but a basic one still remains. print "Today's weather will be $weather->temp degrees and sunny."; This does not DWIM. Instead of interpolating C<$weather->temp> as a method call, it comes out as C<$weather.'->temp'> and is usually followed immediately by the question "What does 'Weather=HASH(0x80d4174)->temp' mean??" Most programmers learning OO Perl expect this to work and are surprised to find that it does not. Work arounds abound: # If I wanted printf(), I'd have written it in C. printf "Today's weather will be %d degrees and sunny.", $weather->temp; my $temp = $weather->temp; print "Today's weather will be $temp degrees and sunny."; print "Today's weather will be @{[$weather->temp]} degrees and sunny."; print "Today's weather will be ".$weather->temp." degrees and sunny."; None are as simple and as obvious as: print "Today's weather will be $weather->{temp} degrees and sunny."; and because of this users groan at having to use accessor methods and are often tempted to violate encapsulation for ease of use. =head2 Proposed Solution - Interpolate Methods Therefore, it is proposed that direct object method calls be interpolated inside double quoted strings and similar constructs. print "Today's weather will be $weather->temp degrees and sunny."; should parse out as: print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; thus returning DWIMness to methods and strings and removing one barrier to accessor method's acceptance over hash lookups for objects. Methods will be run in scalar context. A method which returns a single scalar is treated normally. If a list is returned, it should be treated same as array interpolation. The list seperator will be applied. In effect, the deparsing will really work out as follows: print 'Today\'s weather will be '.join($", $weather->temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). (For the remainder of the RFC, the join() will be assumed when discussing deparsing for brevity.) Should it be decided that a formal distinction be made between accessor methods and other types (RFC 95), method interpolation should interpolate B method. =head2 Argument passing Interpolation should also handle passing arguments to methods in a string: print "Today's weather will be $weather->temp("F") degrees and sunny."; This should deparse to: print 'Today\'s weather will be '.$weather->temp("F"). ' degrees and sunny.'; The arguments to the method are considered as normal expressions, thus: print "There is $obj->foo(this => $yar, that => 2 + 2) in my head."; deparses as: print 'There is '.$obj->foo(this => $yar, that => 2 + 2). ' in my head."; =head1 CAVEATS Indirect object syntax, being already ambiguous, cannot be easily be distinguished in a string from normal text and should not be interpolated. This is ok, since accessors are rarely called with indirect object syntax. Are there any contexts besides double quotes ("", qq{}, <<"EOF") where this need be applied? What about inside regexes? And if so, left and/or right hand side? Normally, whitespace is allowed between tokens of a method call. $obj -> bar ("this"); and $obj->bar("this"); are equivalent. Whitespace between the object, '->', method name and opening paren should be disallowed when interpolated. This will avoid many ambiguous cases. Should the method not exist, Perl will throw an exception/die as usual. C<"$var->{this}[2]{is}->{complex}->method"> should also be interpolated. Also C<"$obj->method->{key}"> for the case where a method returns a reference. =head1 IMPLEMENTATION The behavor of the parser to check for embedded variables would have to be altered, namely the case where an embedded variable is being dereferenced. A case would be added to allow method calls as well as hash and array index dereferences. Otherwise, pars