Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Why won't say act like say when its tied?

by ELISHEVA (Prior)
on Mar 06, 2011 at 19:42 UTC ( [id://891711]=perlquestion: print w/replies, xml ) Need Help??

ELISHEVA has asked for the wisdom of the Perl Monks concerning the following question:

According to say, say is shorthand for { local $\ = "\n"; print LIST }. Consistent with that perltie says that the PRINT method of a tied handle gets called for both print $some_tied_handle and say $some_tied_handle:

PRINT this, LIST
This method will be triggered every time the tied handle is printed to with the print() or say() functions...

However, it seems that when a handle is tied, PRINT is called but local $\="\n" isn't done beforehand. Instead, whatever value of $\ was available before the call to say is used and never overridden. Here is some sample code that demonstrates the issue:

{ package Foo; sub TIEHANDLE { my ($sClass, $fh) = @_; return bless([$fh], $sClass); } sub PRINT { my $self = shift; my $fh = $self->[0]; CORE::print $fh "tied to $self:", @_; } } my $x=gensym; tie *$x, 'Foo', \*STDOUT; local $\="\n***\n"; say "Not tied: I'm just saying ..."; say $x "I'm just saying ..."; # outputs (note that say $x is followed by "\n***\n" # not "\n" # # Not tied: I'm just saying ... # tied to Foo=ARRAY(0x8197ed0):I'm just saying ... # ***

Am I doing something wrong? Is there some trick to making say $some_tied_handle ... act like say STDOUT ...? Or is this a bug? If it is a well known a bug, I didn't have much luck finding it using a general google search. Is there a better way to check to see if a bug is a known perl bug?

Platform is Debian (Lenny) perl=5.10.0

Update: Replaced broken shortcut with explict http link, in light of toolic's reply below.

Replies are listed 'Best First'.
Re: Why won't say act like say when its tied?
by Corion (Patriarch) on Mar 06, 2011 at 19:45 UTC

    I would guess it's a bug, because the program behaves more in line with your (and my) expectations on Perl 5.12:

    use Symbol; use 5.012; { package Foo; sub TIEHANDLE { my ($sClass, $fh) = @_; return bless([$fh], $sClass); } sub PRINT { my $self = shift; my $fh = $self->[0]; CORE::print $fh "tied to $self:", @_; } } my $x=gensym; tie *$x, 'Foo', \*STDOUT; local $\="\n***\n"; say "Not tied: I'm just saying ..."; say $x "I'm just saying ..."; # outputs (note that say $x is followed by "\n***\n" # not "\n" # # Not tied: I'm just saying ... # tied to Foo=ARRAY(0x8197ed0):I'm just saying ... # ***

    This is on Strawberry Perl 5.12:

    This is perl 5, version 12, subversion 1 (v5.12.1) built for MSWin32-x +86-multi-thread
Re: Why won't say act like say when its tied? (OT: link bug)
by toolic (Bishop) on Mar 06, 2011 at 20:03 UTC
    Your link to say is broken due to a previously reported PerlMonks bug (Broken shortcut links for some built-in functions). Normally, I would send a privage /msg regarding broken links, but I decided to go public as a reminder to all the great monks who maintain this site. I wonder if this would be a slam-dunk easy fix for a knowledgeable monk.
Re: Why won't say act like say when its tied?
by ikegami (Patriarch) on Mar 07, 2011 at 07:01 UTC

    The odd thing is, the current code to handle this

    if (flags & TIED_METHOD_SAY) { /* local $\ = "\n" */ SAVEGENERICSV(PL_ors_sv); PL_ors_sv = newSVpvs("\n"); }

    is present in 5.10.0, and there's nothing in perl5101delta about a fix. I wonder if it's a bug Debian introduced. Unfortunately, I can't build 5.10.0 to confirm.

      I was able to install 5.10.0 on a different machine. The bug isn't specific to Debian's build.
Re: Why won't say act like say when its tied?
by ikegami (Patriarch) on Mar 07, 2011 at 04:19 UTC

    For tied handles, say is implemented as

    local $\ = "\n"; print($fh @_);

    Maybe there was a bug in 5.10.0. I tested with 5.10.1 and 5.12.2, and they work fine.

    Lots of bugs were fixed in 5.10 over 1.5 years ago. What's the point of complaining about bugs if you don't even apply the fixes?

      Thank-you for the confirmation that two later versions: 5.10.1 and 5.12.2 do not exhibit this behavior.

      As to the "point" of posting the question? Well, for one, I wasn't 100% convinced the problem wasn't me. But even if I were, 5.10.0 is the system perl for an up-to-date Debian Lenny installation. As the newest Debian release (Sqeeze) was only a few weeks ago (Feb 6, 2011), there are still quite a lot of machines out there running Perl 5.10.0 and will be for some time.

      System administrators are by and large a conservative bunch when it comes to the software running their operating system, so the advice "just upgrade" is usually lost on them. Debian moves slowly to release software updates because it wants to make sure all the different programs work together and it has the philosophy, as do many system administrators, that an old good-enough piece of software with a known bug is better than a shiny new piece of software that hasn't yet been tested for cross reactions with all of the other software on their system.

      Additionally, reports and confirmation of bugs in legacy software can help push the decision to test and prepare for upgrade up the priority list.

      Even when there isn't a potential to fix a bug via a patch or upgrade, I think it helps to know that there is a consensus that strange behavior X is in fact a bug. It allows people who have to work with that version of perl, to move on and focus on workarounds or alternatives rather than spending hours trying to fix something that can't be fixed (without a patch or upgrade).

      In my case, this confirmation meant that I updated a test suite with a version check and added a caveat to some documentation. When I only had Corion's confirmation of a fix in 5.12, those caveats were for all versions before 5.12. Now, with your confirmation of good behavior on 5.10.1, I can lower the version threshold to 5.10.1

      Thank-you again for taking the time to test this and report back on your results.

        I didn't mean to suggest that you just upgrade, I just meant that you should consider that it might have been fixed given that you're testing using a very buggy version of Perl. I realise it didn't come out that way, though. And I now see that you did consider it. Sorry, I missed that.

Re: Why won't say act like say when its tied?
by Anonymous Monk on Mar 07, 2011 at 15:53 UTC
    As a side question, why is say implemented as { local $\="\n"; print LIST } ? The obvious implementation, to me, is print LIST, "\n". Is there a case where that results in bad behavior?

      print appends the value of $\ to the end of whatever is passed to print, so if $\="***\n", then {print "hello", "\n"; } outputs "hello\n***\n" not plain "hello\n". That's why it is important for say to set local $\="\n" and not just add "\n" to the end of the list of things to print. Hope that helps.

        Thanks, it does. So the intended behavior for say is to write exactly what the programmer intended plus \n without side effects from punctuation variables. Good to know.

      It's only done that way for tied handles. Existing tie modules had to support say without being changed, and changing $\ allows that. I suppose they could have done

      local $\; ->PRINT(@_); ->PRINT("\n");

      But if $\ is being localised anyway, might as well do

      local $\ = "\n"; ->PRINT(@_);

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://891711]
Approved by Corion
Front-paged by luis.roca
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-25 12:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found