http://qs321.pair.com?node_id=438514

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

Does it make sense to anyone else that chomp tests and carps about receiving a read-only parameter, before it tests whether it would require modification?

C:\perl-5.8.6>perl -e"chomp( 'fred' )" Can't modify constant item in chomp at -e line 1, at end of line Execution of -e aborted due to compilation errors.

Obviously, it doesn't make much sense to chomp a constant, but if your operating within a sub, you don't know what the user will pass you.

chomp is conditional. If the user passes a constant that doesn't need chomping it would be nice to allow that through without having to duplicate the tests inherent in chomp?


Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco.

20050317 Edit by castaway: Changed title from 'A premature ejaculation?'

Replies are listed 'Best First'.
Re: Should chomping a constant always raise an error?
by BigLug (Chaplain) on Mar 11, 2005 at 03:20 UTC
    Personally, it makes a lot of sense. Sure if there's no need to chomp a value then it shouldn't hurt. However the function *must* be assuming the input it to be modifyied in some way otherwise you'd not pass a value to it that you expect to be modified.
    sub modify { chomp( $_[0] ); # whatever else happens, you've just potentially modified $_[0] } modify('fred'); # What would you expect to happen to 'fred'? my $f ="fred\n"; modify($f); print $f; #fred
    sub modify2 { # Create a copy of the input my $input = $_[0]; chomp($input); } modify('fred'); # works now because we're not modifying the input, but a copy of it. my $f ="fred\n"; modify($f); print $f; #fred\n

    Cheers!
    Rick
    If this is a root node: Before responding, please ensure your clue bit is set.
    If this is a reply: This is a discussion group, not a helpdesk ... If the discussion happens to answer a question you've asked, that's incidental.
      sub modify { chomp( $_[0] ); # whatever else happens, you've just potentially modified $_[0] } modify('fred'); # What would you expect to happen to 'fred'?
      Great example. For those who did not try it out, it causes a runtime exception:
      Modification of a read-only value attempted at /tmp/t.pl line 2.
      Can modify somehow be declared to only take a modifiable parameter, so that we can have a compile-time error (as happens with the core chomp)?
      Can't modify constant item in modify at -e line 1, at end of line Execution of -e aborted due to compilation errors.
        Can modify somehow be declared to only take a modifiable parameter, so that we can have a compile-time error (as happens with the core chomp)?
        Playing Devil's Advocate, will this work?
        chomp(foo(",",@list))
        Don't know? How about this?
        chomp(join(",",@list))
        It seems, off the top of my naive head, that the argument to chomp would have to be an l-value to be guaranteed to be modifiable.

        Is that what you want?

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Re: Should chomping a constant always raise an error?
by Mr. Muskrat (Canon) on Mar 11, 2005 at 03:33 UTC

    Does it make sense to anyone else that chomp tests and carps about receiving a read-only parameter, before it tests whether it would require modification?

    Yes. It is well documented that chomp only works if you give an lvalue to work with.

    I don't want to sound cruel but you want to modify core functionality for a very specific edge case. Good luck getting it implemented.

    It's easier to go with what works. Use a temporary variable if you think that someone will pass you a constant.

      I had no intention of modifying core functionality. I just got surprised by it.


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco.

        Fair enough. I must have read more into your OP.

Re: chomping constants
by Thilosophy (Curate) on Mar 11, 2005 at 03:38 UTC
    In a language as dynamic as Perl, we cannot have a lot of compile-time checks, and I am always happy when it happens, as in this case. I commend the compiler for complaining!

    Obviously, it doesn't make much sense to chomp a constant, but if your operating within a sub, you don't know what the user will pass you.

    I do not quite understand this. Inside of a sub, when the user passes in some data, it would not be a constant, would it?

    If the user passes a constant that doesn't need chomping it would be nice to allow that thtough without having to duplicate the tests inherent in chomp?

    What exactly do you mean by constant? I take it to be something that is known at compile-time.

    I think it would be nice if the compiler optimized away the chomp completely if called with a compile-time constant. But I am not sure this is a feature many people need.

    Update: After reading [id://BigLug]'s response and his excellent examples, I now understand what you meant by "inside of a sub". In this case, I tend to agree with you, that the run-time error that occurs when you pass in a read-only 'fred' (which does not need to be modified) is a little harsh. On the other hand, the subroutine modify wants to modify its parameter and passing constants to it would be as illegal as passing them directly to chomp.

Re: Should chomping a constant always raise an error?
by rir (Vicar) on Mar 11, 2005 at 04:40 UTC
    Yours is a subtle question of typing. Possibly you are only talking about chomp because being a builtin the error is found at compile time; my_chomp won't be caught until runtime.

    I agree with BigLug, it makes sense to complain for finding problems sooner. But this merely indicates that I accept the conventions surrounding const'ness. I don't want to change because the earliest finding of illogical actions in my code makes for easier coding in my view.

    The view you consider, that const'ness be a protection given to a variable, seems less useful. If you wish to play with your idea further here is an imp (I think this is a bad idea as the resulting code seems misleading):

    #!/usr/bin/perl use strict; use warnings; package protected; # constant data that doesn't complain, just doesn't change. # We could have a flag to allow a protected to store a value once; # We could have a "new" subroutine to hide the tied'ness. # Then usage would look like: # use protected; # my $ONE = protected->new; # $ONE = 'one'; sub TIESCALAR { my $class = shift; my $data = shift; return bless { data => $data }, $class; } sub FETCH { return $_[0]->{data} } sub STORE { return $_[0]->{data} } package main; my $THREE; tie $THREE, 'protected', "three "; $THREE = "four"; chomp $THREE; print "\$THREE >$THREE<", $/;
    Be well,
    rir

      That would require anyone calling the sub to tie the constants--which makes no sense at all.

      It just took me by surprise that chomp died when asked to inspect a variable that was readonly. The work-arounds are myriad:

      1. The XS version of Scalar::Util has a readonly function.
      2. I could also use the eval block technique to catch the death. (Which is how the pure Perl version of Scalar::Util::readonly() does it.)
      3. The Internals package has a IsWriteProtected() function.
      4. I could use Inline::C to use the svREADONLY macro.
      5. etc.

      But, as chomp has to determine if there is anything to chomp, before attempting to modify it's argument, I just expected it to make that determination before checking for readonlyness. It doesn't do it that way, so I have to do extra tests or copies myself.

      I've gotten spoiled by Perl's DWIMming things like negative offsets don't die, they work backwards from the end. Same with negative subscripts; ranges that produce no values; empty lists that act correctly regardless of the context etc.

      On this occasion it didn't DWIM for me.


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco.
        Oddly enough, if you use the Readonly module to mark your variable readonly, chomping will only fail if the variable is actually tried to be modified:
        #!/usr/bin/perl use strict; use warnings; use Readonly; Readonly my $msg1 => "Hello, world"; Readonly my $msg2 => "Hello, world\n"; chomp $msg1; # line 11 chomp $msg2; # line 12 __END__ Modification of a read-only value attempted at /tmp/ro line 12
        4. I could use Inline::C to use the svREADONLY macro.
        Done for you, in 5.8.0 and higher: Internals::SvREADONLY($sv)
Re: Should chomping a constant always raise an error?
by cowboy (Friar) on Mar 11, 2005 at 07:00 UTC
    While others have already given you comments for the answer, I feel I must comment on the poor choice of title. Nobody is going to find an answer to their problem, based on this, unless their problem is sexual, and perl code will fix it.
      Yeah, isn't it strange that the people who got all upset about a 3 line node 11 levels deep mentioning 'HaXML' was titled 'HaXML' (instead of inheriting a title mentioning mousetraps in a discussiong that wasn't about mousetraps) because it would screw up searches, now remain silent about the title of this root node?