Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^4: m//g behaves strange... (!1)

by tye (Cardinal)
on Nov 10, 2003 at 05:50 UTC ( #305797=note: print w/ replies, xml ) Need Help??


in reply to Re: Re: Re: m//g behaves strange...
in thread m//g behaves strange...

!1 has a string value of "" and a numeric value of 0 (so as to not generate a warning when used as a number -- 0+"" generates a warning). This is what Perl uses all over the place for 'false' (when it isn't using undef). In the C code for Perl, this is PL_sv_no.

                - tye


Comment on Re^4: m//g behaves strange... (!1)
Download Code
Re: Re^4: m//g behaves strange... (!1)
by pg (Canon) on Nov 10, 2003 at 06:27 UTC

    Yes, I know what you said. If this is the logical answer, so simple and straight, I have used it in my previous post already. Does not seem to me that you have read and understood my previous post carefully. What you said is right, but it does not mean anything here.

    Also I don't understand why you involve !1, when you can simply state that both 0 and "" are "false". How is this "!" operator get involved, when we are talking about "~" operator. They are relatives, but not the same person.

    Although Perl consider multiple values as "false", for a particular function, it usually always returns a single fixed consistent value to represent "false". Ask you an extream question, both 1 and 2 represents "true", when one of your function needs to return "true", will you consistently return 1, or will you sometime return 1 and sometime return 2?

    You failed to answer why should "~" receive 0, when "~" can be applied against "empty string" with no problem, and as we see thru lots of my demo, m// actually returns "empty string" from time to time to represent "false".

    Your 0+"" example also means nothing here. In your case, "+" operator has to be applied to numbers, but in my case, it is absolutely valid to use "~" operator against a string. try this:

    use strict; use warnings; print ~"abcd";

    From a logic point of view, what you did is like: I asked how much 1+1 is, and you answered 2+3=5.

    Update:

    Anonymous Monk's dump is useful, and my further explanation is that:

    • as print requires a string value, so "" is used.
    • for "~", although it can be used against both string and number, when both "" and 0 are available to be used, Perl arbitrarily picks 0.

    One reminder, the dump you given shows ""\0, please don't make up this !1. State what you observed, and only what you observed.

      tye is correct, as usual. The return value of m// when false in scalar context is !1, which is special in that both numeric and string slots are flagged on, with the string value "" and the numeric value 0. The unary ~ op will use the integer value if that flag is on, so it really sees a 0 (not a conversion of the empty string to a numeric value).

      #!/usr/bin/perl -w use strict; use Devel::Peek; my $x = !1; Dump $x; $_ = 'foo'; my $y = /x/; Dump $y; my $z = ""; Dump $z; __END__ SV = PVNV(0x8143040) at 0x81293cc REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,POK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x8124658 ""\0 CUR = 0 LEN = 1 SV = PVNV(0x8143058) at 0x8129384 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,POK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x8126180 ""\0 CUR = 0 LEN = 1 SV = PV(0x811fab8) at 0x81293c0 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x8149ce0 ""\0 CUR = 0 LEN = 1

      So we were both incorrect: the return value is neither "" nor 0 but !1.

        You beat me out - I had an almost identical reply ready when I saw yours. Let me just add that ~ tries to use an integer value even if only a floating-point value is set, and even if it is out of integer range (which can result in some strange results.)

        Also, for any of the bitwise/stringwise ops (~, &, ^, |), quote the variable to force stringwise semanics if you are unsure where it has been:

        $ perl -wle'$x="abc"; print ~$x; print $x+0; print ~$x; print ~"$x"' z?o Argument "abc" isn't numeric in addition (+) at -e line 1. 0 18446744073709551615 z?o
      Does not seem to me that you have read and understood my previous post carefully. What you said is right, but it does not mean anything here.

      I was only adding a bit of information on the subject. That is quite a rant you responded with. Perhaps you should take a step back.

      To be very clear, let's start back at the beginning. You said:

      in scalar context, m// returns either 1 or 0.
      to which AnonyMonk replied:
      <pedantic> actually, m// in scalar context returns either 1 or "" (empty string). </pedantic>.
      And to be extra clear, I'll be blunt: Y'all are both wrong (and y'all are both right). When m// fails in a scalar context, it returns 'the false value'. That is, it returns the standard value that the perl interpreter itself uses all over the place when 'false (but defined)' is to be returned. It is prepopulated with both a string value ("") and a numeric value (0 -- actually both the IV 0 and the NV 0.0 according to the dumps provided by AnonyMonk).

      In C code, this value has a short name, PL_sv_no. When talking Perl, it also deserves a short name. A very short and useful name for it is !1 (useful because you can actually use it in your Perl code when you want a really good 'false' value).

      You failed to answer why should "~" receive 0, when "~" can be applied against "empty string" with no problem, and as we see thru lots of my demo, m// actually returns "empty string" from time to time to represent "false".

      Yes, I didn't say anything about that. I guessed that you already knew why.

      I asked how much 1+1 is, and you answered 2+3=5.

      I didn't see you ask anything. Next time you want to know something, you might want to actually ask the question (or read the docs). I thought you were just pounding a point about how the value that m// returns on failure has '0 nature' at least as much as it has '"" nature'.

      for "~", although it can be used against both string and number, when both "" and 0 are available to be used, Perl arbitrarily picks 0.

      Well, it isn't particularly arbitrary. The bit-wise operators prefer to work on numbers because that is the most expected behavior (this is what they do in C, from which they were borrowed). They prefer numbers to the point that if either operand has ever been used in a numeric context, then numeric results will be returned. This is important because most of the ways Perl code extracts a number from some external source will actually first give you a string (which automatically gets its numeric value when you try to use it as a number).

      To get string values from bit-wise operators, all the operands must have only string values. And this is documented in the docs I link to above.

      And on a personal note, next time you feel that you "asked how much 1+1 is" and someone "answered 2+3=5", you might want to think about why someone might have done such a thing. Although sometimes the answer is that "the answerer is an idiot and a rant would be a good reply", I suppose.

                      - tye
Re: Re^4: m//g behaves strange... (!1)
by !1 (Hermit) on Feb 26, 2004 at 18:59 UTC
    Daddy?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://305797]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2014-09-22 04:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (178 votes), past polls