Re: RFC - Interpolation of method calls
On Mon, Sep 18, 2000 at 01:01:55PM -0400, John Siracusa wrote: > Don't forget the fact that direct access is much faster than a method > call in Perl 5. This will be fixed in Perl 6, of course...right? :) RFC 163 -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Tell your mom to stop calling me. -- Toothgnip www.goats.com
Re: RFC - Interpolation of method calls
>Okay, we get the idea! Only very simple things should interpolate. >Do you have any other objections to the RFCs? Yes: to the mail volume. And I'm about to fix that.
Re: RFC - Interpolation of method calls
On Mon, Sep 18, 2000 at 07:30:37AM -0600, Tom Christiansen wrote: > >So what about > > > print "Thanks, $user->{'first name'} for your order!"; > > >Which needs nested quotes already? > > printf() is more readable in such cases. Okay, we get the idea! Only very simple things should interpolate. Do you have any other objections to the RFCs? -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse With all due respect, BEGONE... sir. - Worf
Re: RFC - Interpolation of method calls
>As Nate pointed out: print "$hash->{'f'.'oo'}" already works fine and >the world spins on. That is no argument for promoting illegibility. --tom
Re: RFC - Interpolation of method calls
On Mon, Sep 18, 2000 at 07:23:41AM -0600, Tom Christiansen wrote: > >> Oh joy: now Perl has nested quotes. I *hate* nested quotes. > >Those are single-quotes inside double-quotes. > > Yep: nested, with varying semantic effects. Completely nasty. As Nate pointed out: print "$hash->{'f'.'oo'}" already works fine and the world spins on. -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse But why? It's such a well designed cesspool of C++ code. Why wouldn't you want to hack mozilla? -- Ziggy
Re: RFC - Interpolation of method calls
On 9/18/00 3:44 AM, Damian Conway wrote: >>> my $weather = new Schwern::Example; >>> print "Today's weather will be $weather->{temp} degrees and sunny."; >>> print "And tomorrow we'll be expecting ", $weather->forecast; >> >> You are wicked and wrong to have broken inside and peeked at the >> implementation and then relied upon it. > > I think the issue is: *what* tempted them to be so wicked and wrong. > It is the fact that iniquitous direct access interpolated easily, whereas > virtuous accessor access didn't. Don't forget the fact that direct access is much faster than a method call in Perl 5. This will be fixed in Perl 6, of course...right? :) -John
Re: RFC - Interpolation of method calls
Tom Christiansen wrote: > > >So what about > > > print "Thanks, $user->{'first name'} for your order!"; > > >Which needs nested quotes already? > > printf() is more readable in such cases. I guess we just have a difference opinion on what consitutes making things easy. -Nate
Re: RFC - Interpolation of method calls
>So what about > print "Thanks, $user->{'first name'} for your order!"; >Which needs nested quotes already? printf() is more readable in such cases. --tom
Re: RFC - Interpolation of method calls
>It hurts me to do this when there's even a little bit of data, since it >ends up spanning lines really quickly. And it's harder to read and >figure out how everything lines up. Honestly, which is easier to read >and code? >print "Thanks, ", $q->param('name'), " for your order of ", >$q->param('amt'), "\n"; >print "Thanks, $q->param('name') for your order of $q->param('amt')\n"; The non-embedded one is easier to read, of course. And this "$q->" crud is a bad choice anyway. If we're going to be mutating Perl just to appease the CGI weenies, then we're doing the wrong thing. Consider: virtually nobody uses that silly OO style with CGI.pm, you know. So you *have* to call print "Thanks, ", param('name'), " for your order of ", param('amt'), "\n"; And anyway, that's ugly. Write that this way if you want it legible: printf "Thanks, %s, for your order of %.02f\n", param('name'), param('amt'); or even printf "Thanks, %s, for your order of %.02f\n", param('name'), param('amt'); >Plus, I notice you ignored my regex example... I don't know what you want me to do about that. You can't do it with backticks either, and for exactly the same reason. If you consider this an onerous burden, then I envy that you have nothing better to annoy you. >-Nate >P.S. I wrote both the above functions on one line, and let my mailer >wrap them @ std 72 cols, Mailers mail. They don't wrap. I suggest you acquire one. --tom
Re: RFC - Interpolation of method calls
>> Oh joy: now Perl has nested quotes. I *hate* nested quotes. >Those are single-quotes inside double-quotes. Yep: nested, with varying semantic effects. Completely nasty. -tom
Re: RFC - Interpolation of method calls
Tom Christiansen wrote: > > You are wicked and wrong to have broken inside and peeked at the > implementation and then relied upon it. I agree completely. So Perl should make it easier to deal with class methods. > >I find myself wanting to say: > > > print "Thanks, $cgi->param('name') for your order!"; > > print "It matched" if /$config->get_expression/; > > Oh joy: now Perl has nested quotes. I *hate* nested quotes. > They're terrible. See the shell for how icky this is. So what about print "Thanks, $user->{'first name'} for your order!"; Which needs nested quotes already? > > print "Thanks, " . $cgi->param('name') . " for your order"; > > What's the big deal? How does it hurt you to do that? It hurts me to do this when there's even a little bit of data, since it ends up spanning lines really quickly. And it's harder to read and figure out how everything lines up. Honestly, which is easier to read and code? print "Thanks, ", $q->param('name'), " for your order of ", $q->param('amt'), "\n"; print "Thanks, $q->param('name') for your order of $q->param('amt')\n"; Plus, I notice you ignored my regex example... -Nate P.S. I wrote both the above functions on one line, and let my mailer wrap them @ std 72 cols, so any wrapping is not artificially induced by myself in some odd attempt to prove a point.
Re: RFC - Interpolation of method calls
On Mon, Sep 18, 2000 at 01:12:10AM -0600, Tom Christiansen wrote: > You are wicked and wrong to have broken inside and peeked at the > implementation and then relied upon it. That's a new one for perldiag. Would that be (S) or (X)? > > print "Thanks, $cgi->param('name') for your order!"; > > print "It matched" if /$config->get_expression/; > > Oh joy: now Perl has nested quotes. I *hate* nested quotes. Those are single-quotes inside double-quotes. -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Plus I remember being impressed with Ada because you could write an infinite loop without a faked up condition. The idea being that in Ada the typical infinite loop would be normally be terminated by detonation. -- Larry Wall in <[EMAIL PROTECTED]>
Re: RFC - Interpolation of method calls
> > my $weather = new Schwern::Example; > > print "Today's weather will be $weather->{temp} degrees and sunny."; > > print "And tomorrow we'll be expecting ", $weather->forecast; > > You are wicked and wrong to have broken inside and peeked at the > implementation and then relied upon it. I think the issue is: *what* tempted them to be so wicked and wrong. It is the fact that iniquitous direct access interpolated easily, whereas virtuous accessor access didn't. Perhaps this RFC should be subtitled: "Ne nos inducas in tentationem..." :-) Damian
Re: RFC - Interpolation of method calls
>I doubt anyone's arguing that they're not function calls. What I find >"surprising" is that Perl doesn't DWIM here. It doesn't encourage data >encapsulation or try to make it easy: > my $weather = new Schwern::Example; > print "Today's weather will be $weather->{temp} degrees and sunny."; > print "And tomorrow we'll be expecting ", $weather->forecast; You are wicked and wrong to have broken inside and peeked at the implementation and then relied upon it. >If method calls interpolated, this would be easier. Instead, it >encourages you to provide direct hash access to your data since it's >much easier to use that way. >I find myself wanting to say: > print "Thanks, $cgi->param('name') for your order!"; > print "It matched" if /$config->get_expression/; Oh joy: now Perl has nested quotes. I *hate* nested quotes. They're terrible. See the shell for how icky this is. >Rather than: > print "Thanks, " . $cgi->param('name') . " for your order"; What's the big deal? How does it hurt you to do that? And why are you catting it instead of simply passing a list? --tom
Re: RFC - Interpolation of method calls
Tom Christiansen wrote: > > Funny--I always think of them as function calls, and don't expect > function calls to expand. I doubt anyone's arguing that they're not function calls. What I find "surprising" is that Perl doesn't DWIM here. It doesn't encourage data encapsulation or try to make it easy: my $weather = new Schwern::Example; print "Today's weather will be $weather->{temp} degrees and sunny."; print "And tomorrow we'll be expecting ", $weather->forecast; If method calls interpolated, this would be easier. Instead, it encourages you to provide direct hash access to your data since it's much easier to use that way. I find myself wanting to say: print "Thanks, $cgi->param('name') for your order!"; print "It matched" if /$config->get_expression/; Rather than: print "Thanks, " . $cgi->param('name') . " for your order"; my($tmp_exp) = $config->get_expression; print "It matched" if /$tmp_exp/; So often it almost hurts. This proposal makes things easier. And to me it remains quite consistent if we say: -> is always special, even in qq//, just like $ and @ For hashrefs and arrayrefs, this already appears to be true anyways. -Nate
Re: RFC - Interpolation of method calls
On Sun, Sep 17, 2000 at 08:56:23PM -0600, Tom Christiansen wrote: > While you're there, you should fix it to spell piñatas properly. :-( > We're not talking about stands of pine trees, presumably. Funny, I know how to type extended characters in MacOS, but I have no idea how to do it in X. Hell, my font doesn't even display them right. *grumble* -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse BOFH excuse #270: Someone has messed up the kernel pointers
Re: RFC - Interpolation of method calls
># $inventory->pinatas returns a list of pinatas we have. ># "Yes, El Guapo, I would say I have 23 pinatas\n"; >print "Yes, El Guapo, I would say I have $inventory->pinatas pinatas\n"; >I appear to have a new version of the RFC ready without the first even >having made it out to the public! While you're there, you should fix it to spell piñatas properly. :-( We're not talking about stands of pine trees, presumably. --tom
Re: RFC - Interpolation of method calls
>I think it's far more inconsistent to have the above work but not have >methods interpolate. And yes, I realize they're different thingies but >they're very close syntactically and cognitively, Funny--I always think of them as function calls, and don't expect function calls to expand. >especially for data >access (which is really what we're talking about here). --tom
Re: RFC - Interpolation of method calls
Sorry, I wasn't subscribed to perl6-language-objects and didn't even realize there was a discussion going on. I just fixed that. I didn't mean to hijack RFC 103, I can't remember if I'd even looked at it before... but Nathan seems okay with that and it is a deceptively large issue. Version 2 of the RFC went out last night (I'll have to do v3 after reading these comments) and clarifies a few things (the changes are all listed at the top). Most importantly, C<"$weather->temp("F")"> was a typo. It should have been C<"$weather->temp(\"F\")">. Also, RFCs about interpolation of class methods and subroutines also went out last night, so I'll let them speak for themselves. Now, about that context thing. The main conundrum is what to do with methods that return a list. Would it be best to just let it be scalar context? # $inventory->pinatas returns a list of pinatas we have. # "Yes, El Guapo, I would say I have 23 pinatas\n"; print "Yes, El Guapo, I would say I have $inventory->pinatas pinatas\n"; Or would it be better to expand the returned list, as arrays are expanded with C? Now that I think about it, its fairly obvious that simple scalar context is best. Why? I can't even think of a useful example of the list expansion. Most of the time you want to seperate them with a ", " anyway, not with $". So junk that bit about the context weirdness. Simple scalar context it is. Nathan already covered the questions about evaluating expressions and arguments. Perl already does it for everything else. Furthermore, interpolating the expression should be simple, as I realized later while writing the RFC for interpolatoin of subroutines. The tokenizer can watch for /&[A-Z_]\w*/i. If followed by a '(', then the parsing becomes the same as for normal subroutine arguments excepting that it must watch for an unescaped closing string character. I'm also glad to find out Perl already disallows whitespace for other interpolated constructs. I appear to have a new version of the RFC ready without the first even having made it out to the public! -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Many people think that an UFO is probably propelled by some kind of antigravity magnetic motor. I have a totally different thinking. I believe that an UFO is propelled by jet engine. UFO's gyroscopic body rotates and serves as its wing to keep UFO's body balanced in the air. --Alex Chiu, Immortality Guy
Re: RFC - Interpolation of method calls
Tom Christiansen wrote: > > >print "Today's weather will be $weather->temp degrees and sunny."; > > So, the -> operator is supposed to get expanded in dq strings, eh? It already does, or at least appears to to users: print "Today's weather will be $weather->{temp} degrees and sunny."; print "Today's weather will be $weather->[0] degrees and sunny."; > Isn't it inconsistent to do this? I think it's far more inconsistent to have the above work but not have methods interpolate. And yes, I realize they're different thingies but they're very close syntactically and cognitively, especially for data access (which is really what we're talking about here). I've always found it quite surprising and cumbersome to have to do this: print "Today's weather will be ", $weather->temp, " degrees and sunny."; When the above two work fine. -Nate
Re: RFC - Interpolation of method calls
On Sun, Sep 17, 2000 at 07:55:43PM -0600, Tom Christiansen wrote: > So, the -> operator is supposed to get expanded in dq strings, eh? > > What about class methods, like "Give him Employee->salary() again"? Because I knew this would raise problems, "Interpolation of class method calls" was presented as a seperate RFC and answers your questions (or takes a good swing at it). Also "Interpolation of subroutines". They were posted to perl6-rfc very late last night, along with version 2 of RFC 222, and should be reaching the announcement list soon. -- Michael G Schwern http://www.pobox.com/~schwern/ [EMAIL PROTECTED] Just Another Stupid Consultant Perl6 Kwalitee Ashuranse Cheating is often more efficient. - Seven of Nine
Re: RFC - Interpolation of method calls
>Or DWIM "${\foo()}" to force scalar context. Everytime I come across that >construct I have to wonder why it's not called in scalar context. The '$' >would seem to imply it should. Huh? No more than $x = scalar reverse fn(); would cause reverse() to call fn() in scalar context. The reverse() listop confers list context upon its right-hand operand(s). Likewise, so too does the \ listop confer list context upon its right-hand operand. >I have to assume \foo() is actually \(foo()) or some such. I don't know what that means. \foo() is \foo(). It's not any different than \(foo()), and certainly not meriting an "actually". IMHO, this is >entirely non-intuitive. Can anyone enlighten me as to why this is as it is? >I believe there was a p5p discussion about this, but I dread delving into >the archives again.. Try this, from the Third Camel('s old draft): As mentioned earlier, the backslash operator, although usually used on a single referent to generate a single reference, doesn't have to be. When used on a list of referents, it produces a list of corresponding references. The second line of both pairs of examples below does the same thing as the first line, but has the backslash automatically distributed throughout the whole list. @reflist = (\$s, \@a, \%h, \&f); # List of four references @reflist = \($s, @a %h, &f); # Same thing If a parenthesized list contains exactly one array or hash, then all of its values are interpolated and references to each returned. @reflist = \(@x);# Interpolate array, then get refs @reflist = map { \$_ } @x; # Same thing This also occurs when there are internal parentheses: @reflist = \(@x, (@y));# But only single aggregates expand @reflist = (\@x, map { \$_ } @y);# Same thing If you try this with a hash, the result will contain references to the values (as you'd expect), but references to I of the keys (as you might not expect). Since array and hash slices are really just lists, you can backslash a slice of either of these to get a list of references. Each of the next three lines does exactly the same thing. @envrefs = \@ENV{'HOME', 'TERM'}; # Backslashing a slice @envrefs = \( $ENV{HOME}, $ENV{TERM} ); # Backslashing a list @envrefs = ( \$ENV{HOME}, \$ENV{TERM} ); # A list of two references Since functions can return lists, you can apply a backslash to them. If you have more than one function to call, first interpolate each function's return values into a larger list and then backslash the whole thing. @reflist = \fx(); @reflist = map { \$_ } fx();# Same thing @reflist = \( fx(), fy(), fz() ); @reflist = ( \fx(), \fy(), \fz() ); # Same thing @reflist = map { \$_ } fx(), fy(), fz();# Same thing The backslash operator always supplies a list context to its operand, so those functions are all called in list context. If the backslash is itself in scalar context, you'll end up with a reference to the last value from the list returned by the function. @reflist = \localtime(); # Ref to each of nine time elements $lastref = \localtime(); # Ref to whether it's daylight savings time In this regard, the backslash behaves like the named Perl list operators, such as C, C, and C, which always supply a list context on their right no matter what might be happening on their left. As with named list operators, use an explicit C to force what follows into scalar context. $dateref = \scalar localtime();# \"Sat Jul 16 11:42:18 2000" --tom
Re: RFC - 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."; >Would deparse to: >print 'Today\'s weather will be '.$weather->temp().' degrees and sunny.'; So, the -> operator is supposed to get expanded in dq strings, eh? What about class methods, like "Give him Employee->salary() again"? Or what about things like "move lost->found"? What does that do? And why is -> special then? What about "move lost+found"? Surely we can't be adding those now! Isn't it inconsistent to do this? --tom
Re: RFC - Interpolation of method calls
On Fri, Sep 15, 2000 at 07:24:39PM -0500, David L. Nicol wrote: > > 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. > > $ perl -le 'sub w{wantarray?"WA":"WS"};print " attempt: ${\scalar(w)}"' > attempt: WS > > Maybe we just need a shorter synonym for C? Or DWIM "${\foo()}" to force scalar context. Everytime I come across that construct I have to wonder why it's not called in scalar context. The '$' would seem to imply it should. Or cause the foo() method in "foo $foo->bar bar" to be called in scalar context by default, obviating the need for a specific scalar call. I'd actually like both solutions to be implemented. What's even more confusing: sub foo { wantarray ? "list" : "scalar" } print scalar("${\foo()}") --> "list" print scalar(${\foo()}) --> "list" $foo = ${\foo()}; print $foo--> "list" And yet: sub foo { wantarray ? \"list" : \"scalar" } print ${foo()} --> "scalar" print ${ ("bar", foo()) } --> "scalar" (These were all tested using 5.6.0.) I have to assume \foo() is actually \(foo()) or some such. IMHO, this is entirely non-intuitive. Can anyone enlighten me as to why this is as it is? I believe there was a p5p discussion about this, but I dread delving into the archives again.. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC - Interpolation of method calls
> 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. $ perl -le 'sub w{wantarray?"WA":"WS"};print " attempt: ${\scalar(w)}"' attempt: WS Maybe we just need a shorter synonym for C?
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 --
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 - 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: 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 --
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