in reply to Re: Re: Scalars, Lists, and Arrays
in thread Scalars, Lists, and Arrays

There are other contexts as well. Camel III lists three of them. They are:

Replies are listed 'Best First'.
Re: Re: Re: Re: Scalars, Lists, and Arrays
by chromatic (Archbishop) on Apr 13, 2001 at 20:39 UTC
    Void context is where you have an expression (not to abuse Dominus' terminology too much) that doesn't go anywhere. For example, if you had:
    open(FILE, $filename) or die "Can't open $filename: $!"; "nothing to see here"; close FILE;
    Ignoring the fact that the program does nothing, the second line is a scalar expression (help me out here, if I abuse verbiage) in void context.

    When you abuse map to iterate over a list and don't assign the results to anything, you're using map in void context.

    It's generally not useful, but if you have an expression that can spend a lot of time creating a result value of some sort, it can be inefficient to use void context.

Re: Scalars, Lists, and Arrays
by Dominus (Parson) on Apr 13, 2001 at 21:02 UTC
    Says sierrathedog04:
    Boolean context is ubiquitous, so let's give this little brother of list and scalar its due!
    "Boolean context" is 100% identical with scalar context. It is a fiction.

    Interpolative context
    That is not a context, because expressions are not evaluated in double-quoted strings. What value does localtime() produce in "The time is: localtime()\n"?

    Void context
    This one is a little different. For built-in Perl operators, it's identical to scalar context. The only time it might be different is for a user-defined function that explicitly tests whether wantarray yields an undefined value, and which does something different if so. Regardless, there's no question about what the return value is.

    The interesting one I think you left out is that the argument of defined is a different kind of context. defined(&foo) doesn't even call &foo.

      *sigh* let's not go overboard on what can and can't be called a "context", either.

      So-called "Boolean context" is a useful concept, especially if you are dealing with overloaded objects. I agree that it is important to realize that it isn't a "context" in the same way that "scalar context", "list context", and "void context" are and that using something in a "Boolean context" is hard to distinguish from using it in a scalar context (though it can be done by using overloading). I'd love to see an enhancement that elevates "Boolean context" to being a "first class context" (well, at least "second class" if you don't count "void" as "first class") by, for example, adding a OPf_WANT_BOOL flag.

      "Interpolative context" can also be a valuable concept for explaining why these are different:

      print "@a"; print "".@a; print @a;
      even though it is very much different than the "big three" contexts. This one reminds me of the "numeric", "string", and "integer" pseudo contexts.

      For built-in Perl operators, [void context] is identical to scalar context

      Doing a quick search, I found that keys knows the difference between scalar and void context so that it can avoid some work in the latter case. I suspect there are more than a few other cases. I'm not trying to contradict you, I just don't want others to overinterpret what you are saying.

      I guess that by "do something different" (in the case of a user-defined function detecting void context) you are referring to "side effects" and that you are asserting that no built-in functions/operators of Perl have different side effects between scalar and void context. I would certainly be somewhat surprised to find a case that violates such an assertion but I wouldn't feel comfortable making that assertion myself.

      I'd take issue with your using "context" to describe the special way defined works but that would just seem ornery of me. A similar "context" that I'm finding increasingly interesting is the "pseudo code block context" that is given to the first argument of map or grep:

      map func($_), @list; grep func($_), @list;

              - tye (but my friends call me "Tye")
Re4: Scalars, Lists, and Arrays
by sachmet (Scribe) on Apr 13, 2001 at 20:41 UTC
    Void context ... Maybe its best to avoid this one altogether

    Void context is where you're performing an operation and doing nothing with the result. That is,
    #!/usr/bin/perl -cw "String";
    tells me:
    Useless use of a constant in void context at - line 2.
    In fact, I care about this because it generally indicates a problem with my program. What use is a constant where I don't store what that constant is?

    Void context can be useful. Consider:
    grep { s/\s+$// } @lines;
    which will remove all trailing whitespace from all the lines I have in @lines. grep normally returns the lines that matched the pattern. But because I'm in void context, the values just get thrown away and all I'm left with is @lines which contains every line missing its trailing whitespace. (By the way, the better way to do that is:
    foreach (@lines) { s/\s+$// }

    Consider also that some objects require methods to be run in void context. While you're not just throwing away their values, these things have side effects that perform useful work. For example, in CGI, you can do:
    which, while run in void context, imports all parameters into the 'R' namespace.

    So, in summary, -w isn't complaining because you're running things in void context. It's complaining because you're running in void context without doing anything that could be construed as useful.

    Update: D'oh, chromatic beat me to it.