using wildcards with -e

Discussion in 'Perl Misc' started by DMB, Jun 27, 2007.

  1. DMB

    DMB Guest

    I have the following code:

    if (-e $done_dir."BOB.DOC") {
    print "found it\n";
    } else {
    print "nope\n";
    }

    where $done_dir contains the directory path of the file I'm looking
    for.

    I'd like to make it so that it doesn't matter what the filename is.
    I'm only interested in the suffix. I was thinking along the lines
    of...

    if (-e $done_dir."*.DOC") {
    print "found it\n";
    } else {
    print "nope\n";
    }

    but of course this does not work in perl. I'm sure there is an easy
    solution to this, but I can't seem to find a example online or in any
    of my books of using -e and wildcards.

    Thank you for your assistance.
     
    DMB, Jun 27, 2007
    #1
    1. Advertising

  2. DMB <> writes:

    > I'd like to make it so that it doesn't matter what the filename is.
    > I'm only interested in the suffix. I was thinking along the lines
    > of...
    >
    > if (-e $done_dir."*.DOC") {
    > print "found it\n";
    > } else {
    > print "nope\n";
    > }


    You might want to look at the glob function which expands these kinds
    of wildcards into a list of files. So something like

    if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    print "Found it";
    }

    //Makholm
     
    Peter Makholm, Jun 27, 2007
    #2
    1. Advertising

  3. DMB

    DMB Guest

    On Jun 27, 4:13 pm, Peter Makholm <> wrote:
    > DMB <> writes:
    > > I'd like to make it so that it doesn't matter what the filename is.
    > > I'm only interested in the suffix. I was thinking along the lines
    > > of...

    >
    > > if (-e $done_dir."*.DOC") {
    > > print "found it\n";
    > > } else {
    > > print "nope\n";
    > > }

    >
    > You might want to look at the glob function which expands these kinds
    > of wildcards into a list of files. So something like
    >
    > if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    > print "Found it";
    >
    > }
    >
    > //Makholm


    Great! I'm reading on glob now. I'm not sure I fully understand it
    yet, but your example worked perfectly when I tested it.

    Thank you.
     
    DMB, Jun 27, 2007
    #3
  4. Peter Makholm wrote:
    > DMB <> writes:
    >
    >> I'd like to make it so that it doesn't matter what the filename is.
    >> I'm only interested in the suffix. I was thinking along the lines
    >> of...
    >>
    >> if (-e $done_dir."*.DOC") {
    >> print "found it\n";
    >> } else {
    >> print "nope\n";
    >> }

    >
    > You might want to look at the glob function which expands these kinds
    > of wildcards into a list of files. So something like
    >
    > if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    > print "Found it";
    > }


    You shouldn't need the grep, this should work:

    if ( glob "$donedir/*.DOC" ) {
    print "Found it";
    }


    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
     
    John W. Krahn, Jun 27, 2007
    #4
  5. On Wed, 27 Jun 2007 21:07:40 -0000, DMB <> wrote:

    >if (-e $done_dir."*.DOC") {
    > print "found it\n";
    >} else {
    > print "nope\n";
    >}
    >
    >but of course this does not work in perl. I'm sure there is an easy
    >solution to this, but I can't seem to find a example online or in any
    >of my books of using -e and wildcards.


    if (grep -e, glob "$done_dir*.DOC") {


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Jun 28, 2007
    #5
  6. On Wed, 27 Jun 2007 22:18:02 GMT, "John W. Krahn" <>
    wrote:

    >You shouldn't need the grep, this should work:
    >
    >if ( glob "$donedir/*.DOC" ) {
    > print "Found it";
    >}


    D'Oh! Just as obvious as I also missed that!


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Jun 28, 2007
    #6
  7. "John W. Krahn" <> writes:

    >> if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    >> print "Found it";
    >> }

    >
    > You shouldn't need the grep, this should work:
    >
    > if ( glob "$donedir/*.DOC" ) {
    > print "Found it";
    > }


    How could I miss that. I didn't even think about what kind of file
    test was being used.

    //Makholm
     
    Peter Makholm, Jun 28, 2007
    #7
  8. DMB

    Paul Lalli Guest

    On Jun 27, 6:18 pm, "John W. Krahn" <> wrote:
    > Peter Makholm wrote:
    > > DMB <> writes:

    >


    > >> if (-e $done_dir."*.DOC") {
    > >> print "found it\n";
    > >> } else {
    > >> print "nope\n";
    > >> }

    >
    > > You might want to look at the glob function which expands these
    > > kinds of wildcards into a list of files. So something like

    >
    > > if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    > > print "Found it";
    > > }

    >
    > You shouldn't need the grep, this should work:
    >
    > if ( glob "$donedir/*.DOC" ) {
    > print "Found it";
    > }


    Danger, danger Will Robinson!! That bit of code will work only if
    both of the following are true:
    1) The string actually does contain shell meta characters.
    2) The block is not being used in a loop.

    If you later change your "pattern" to actualy be a single file, your
    code will break. This is especially a problem if you're reading the
    pattern from the user. Observe:

    ~/temp $ ls
    ~/temp $ perl -le'print for glob("foo.*")'
    ~/temp $ perl -le'print for glob("foo.bar")'
    foo.bar
    ~/temp $

    If the code is being called in a loop of some kind, and there are, say
    N files that match the pattern, your if statement will fail every (N
    +1)th time. Observe:

    ~/temp $ touch foo.1 foo.2 foo.3
    ~/temp $ perl -le'
    for (1..10) {
    if (glob("foo.*")) {
    print "yes"
    } else {
    print "no"
    }
    }
    '
    yes
    yes
    yes
    no
    yes
    yes
    yes
    no
    yes
    yes


    All things considered, it's better to stick with the grep, and thereby
    call glob() in a scalar context, explicitly testing the existance of
    each return value.

    Paul Lalli
     
    Paul Lalli, Jun 28, 2007
    #8
  9. DMB

    Paul Lalli Guest

    On Jun 28, 1:12 pm, Paul Lalli <> wrote:

    > All things considered, it's better to stick with the grep, and
    > thereby call glob() in a scalar context, explicitly testing the
    > existance of each return value.


    s/scalar/list/;

    Paul Lalli
     
    Paul Lalli, Jun 28, 2007
    #9
  10. On Thu, 28 Jun 2007 10:12:29 -0700, Paul Lalli <>
    wrote:

    >If you later change your "pattern" to actualy be a single file, your
    >code will break. This is especially a problem if you're reading the
    >pattern from the user. Observe:


    Oh, yeah, and there' brace expansion too. Perhaps it was not that bad
    to leave the -e in after all...


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Jun 28, 2007
    #10
  11. Paul Lalli wrote:
    > On Jun 27, 6:18 pm, "John W. Krahn" <> wrote:
    >> Peter Makholm wrote:
    >>> DMB <> writes:

    >>

    >
    >>>> if (-e $done_dir."*.DOC") {
    >>>> print "found it\n";
    >>>> } else {
    >>>> print "nope\n";
    >>>> }

    >>
    >>> You might want to look at the glob function which expands these
    >>> kinds of wildcards into a list of files. So something like

    >>
    >>> if (grep { -e $_ } glob("$donedir/*.DOC") ) {
    >>> print "Found it";
    >>> }

    >>
    >> You shouldn't need the grep, this should work:
    >>
    >> if ( glob "$donedir/*.DOC" ) {
    >> print "Found it";
    >> }

    >
    > Danger, danger Will Robinson!! That bit of code will work only if
    > both of the following are true:
    > 1) The string actually does contain shell meta characters.
    > 2) The block is not being used in a loop.
    >
    > If you later change your "pattern" to actualy be a single file, your
    > code will break. This is especially a problem if you're reading the
    > pattern from the user. Observe:
    >
    > ~/temp $ ls
    > ~/temp $ perl -le'print for glob("foo.*")'
    > ~/temp $ perl -le'print for glob("foo.bar")'
    > foo.bar
    > ~/temp $
    >
    > If the code is being called in a loop of some kind, and there are, say
    > N files that match the pattern, your if statement will fail every (N
    > +1)th time. Observe:
    >
    > ~/temp $ touch foo.1 foo.2 foo.3
    > ~/temp $ perl -le'
    > for (1..10) {
    > if (glob("foo.*")) {
    > print "yes"
    > } else {
    > print "no"
    > }
    > }
    > '
    > yes
    > yes
    > yes
    > no
    > yes
    > yes
    > yes
    > no
    > yes
    > yes


    I noticed that if you change:

    if (glob("foo.*")) {

    to [1]:

    my @files = glob("foo.*");
    if (@files) {

    then you get:

    $ ./test.pl
    yes
    yes
    yes
    yes
    yes
    yes
    yes
    yes
    yes
    yes

    Changing the contents of the loop to [2]:

    my @files = glob("foo.*");
    print "[". join("]\n[", @files). "]\n\n";

    prints the following 10 times:

    [foo.1]
    [foo.2]
    [foo.3]

    > All things considered, it's better to stick with the grep, and thereby
    > call glob() in a scalar context, explicitly testing the existance of
    > each return value.
    >
    > Paul Lalli


    Grep works fine. But I want to know why Glob returns the way it does in
    your original code?

    In fact, if you change your original 'if' statement to:

    if (()=glob("foo.*")) {

    then 'yes' is printed every time as expected. Of course, it's being
    forced into list context. It seems glob in scalar context is the
    problem.


    According to my Perl Pocket Reference (4th Ed.), pg 54:

    glob expr ?
    Returns a list of filenames that match the C-shell
    pattern(s) in expr.


    Perldoc says this:

    $ perldoc -f glob
    glob EXPR
    glob Returns the value of EXPR with filename expansions
    such as the standard Unix shell /bin/csh would do.
    This is the internal function implementing the
    "<*.c>" operator, but you can use it directly.


    So if used in scalar context, shouldn't it be returning 3 (the list
    count) in the example we're using?

    It seems it shouldn't matter if it's being used in a loop or not, it
    should be returning the same each time since what it's fetching is
    unchanged?

    Does this mean glob is broken in scalar context?



    [1]
    #!/usr/bin/perl

    use strict;

    for (1..10) {
    my @d = glob("foo.*");
    if (@d) {
    #if (glob("foo.*")) {
    print "yes"
    }
    else {
    print "no"
    }

    print "\n";
    }
    __END__


    [2]

    #!/usr/bin/perl

    use strict;

    for (1..10) {
    my @files = glob("foo.*");
    print "[". join("]\n[", @files). "]\n\n";
    }
    __END__

    --
    CL
     
    Clenna Lumina, Jun 28, 2007
    #11
  12. DMB

    Paul Lalli Guest

    On Jun 28, 2:49 pm, "Clenna Lumina" <> wrote:

    > Grep works fine. But I want to know why Glob returns the way it
    > does in your original code?


    Because glob() does something different depending on if its called in
    scalar context or list context.

    > In fact, if you change your original 'if' statement to:
    >
    > if (()=glob("foo.*")) {
    >
    > then 'yes' is printed every time as expected. Of course, it's being
    > forced into list context. It seems glob in scalar context is the
    > problem.


    Yes.

    > According to my Perl Pocket Reference (4th Ed.), pg 54:
    >
    > glob expr ?
    > Returns a list of filenames that match the C-shell
    > pattern(s) in expr.


    Your pocket reference is wrong. It only returns a list in list
    context.

    > Perldoc says this:
    >
    > $ perldoc -f glob
    > glob EXPR
    > glob Returns the value of EXPR with filename expansions
    > such as the standard Unix shell /bin/csh would do.
    > This is the internal function implementing the
    > "<*.c>" operator, but you can use it directly.


    You either have an old and/or broken version of Perldoc, or you oddly
    omitted a section. In my perldoc, there is another sentence between
    those two:
    In scalar
    context, glob iterates through such filename
    expansions, returning undef when the list is
    exhausted.

    > So if used in scalar context, shouldn't it be returning 3 (the list
    > count) in the example we're using?


    I don't know what makes you think that. Even if your version of the
    doc was complete, it still doesn't say that. You may be falling into
    the trap of believing that all list-returning functions return the
    size of that list in scalar context. That's not true. Arrays
    evaluated in scalar context return their size. That's it. You cannot
    generalize "array" to "any expression returning a list." Any function
    returning a list of values in list context is free to do anything else
    in scalar context.

    > Does this mean glob is broken in scalar context?


    No. glob() behaves exactly as it's documented to behave in scalar
    context. If your version of perldoc really is missing that critical
    section, I suggest you check out the most recent version:
    http://perldoc.perl.org/functions/glob.html

    Paul Lalli
     
    Paul Lalli, Jun 28, 2007
    #12
  13. Paul Lalli wrote:
    > On Jun 28, 2:49 pm, "Clenna Lumina" <> wrote:
    >
    >> Grep works fine. But I want to know why Glob returns the way it
    >> does in your original code?

    >
    > Because glob() does something different depending on if its called in
    > scalar context or list context.


    Would it not of been more logical to have it return the count of the
    files it found, though?

    >> In fact, if you change your original 'if' statement to:
    >>
    >> if (()=glob("foo.*")) {
    >>
    >> then 'yes' is printed every time as expected. Of course, it's being
    >> forced into list context. It seems glob in scalar context is the
    >> problem.

    >
    > Yes.
    >
    >> According to my Perl Pocket Reference (4th Ed.), pg 54:
    >>
    >> glob expr ?
    >> Returns a list of filenames that match the C-shell
    >> pattern(s) in expr.

    >
    > Your pocket reference is wrong. It only returns a list in list
    > context.


    That would seem to be the case.

    >> Perldoc says this:
    >>
    >> $ perldoc -f glob
    >> glob EXPR
    >> glob Returns the value of EXPR with filename expansions
    >> such as the standard Unix shell /bin/csh would do.
    >> This is the internal function implementing the
    >> "<*.c>" operator, but you can use it directly.

    >
    > You either have an old and/or broken version of Perldoc, or you oddly
    > omitted a section. In my perldoc, there is another sentence between
    > those two:


    Hmm, I'm using Perl 5.6.1 on RH Linux and it does seem to lack that
    section:

    perldoc -f glob
    glob EXPR
    glob Returns the value of EXPR with filename expansions
    such as the standard Unix shell /bin/csh would do.
    This is the internal function implementing the
    "<*.c>" operator, but you can use it directly. If
    EXPR is omitted, "$_" is used. The "<*.c>" opera-
    tor is discussed in more detail in the I/O Opera-
    tors entry in the perlop manpage.

    Beginning with v5.6.0, this operator is imple-
    mented using the standard "File::Glob" extension.
    See the File::Glob manpage for details.
    (END)

    > In scalar
    > context, glob iterates through such filename
    > expansions, returning undef when the list is
    > exhausted.


    Well that certainly explains it. FWIW, my pocket book (ISBN
    0-596-00374-9) claims it covers Perl 5.8, so it's a little odd that they
    left this rather important note out. Same goes for 5.6.1's Perldoc.

    >> So if used in scalar context, shouldn't it be returning 3 (the list
    >> count) in the example we're using?

    >
    > I don't know what makes you think that. Even if your version of the
    > doc was complete, it still doesn't say that. You may be falling into
    > the trap of believing that all list-returning functions return the
    > size of that list in scalar context. That's not true. Arrays
    > evaluated in scalar context return their size. That's it. You cannot
    > generalize "array" to "any expression returning a list." Any function
    > returning a list of values in list context is free to do anything else
    > in scalar context.


    Hmm, thanks for pointing that out. Yes it is easy to get into that way
    of thinking, when many functions seem to return the count (ie, map,
    grep) when used in scalar context.

    >> Does this mean glob is broken in scalar context?

    >
    > No. glob() behaves exactly as it's documented to behave in scalar
    > context.


    Question retracted.

    > If your version of perldoc really is missing that critical
    > section, I suggest you check out the most recent version:
    > http://perldoc.perl.org/functions/glob.html


    Thank you, I have saved this.

    --
    CL
     
    Clenna Lumina, Jun 28, 2007
    #13
  14. DMB

    Paul Lalli Guest

    On Jun 28, 3:12 pm, "Clenna Lumina" <> wrote:
    > Paul Lalli wrote:
    > > On Jun 28, 2:49 pm, "Clenna Lumina" <>
    > > wrote:

    >
    > >> Grep works fine. But I want to know why Glob returns the way
    > >> it does in your original code?

    >
    > > Because glob() does something different depending on if its
    > > called in scalar context or list context.

    >
    > Would it not of been more logical to have it return the count
    > of the files it found, though?


    Not really. Think of glob() as a means of doing readdir() via shell
    expansion rather than opening the directory in Perl. That way, you
    can do:
    while (my $file = glob("*.pl")) {
    #...
    }
    rather than:
    open my $dh, "." or die $!;
    while (my $file = readdir($dh)) {
    next unless $file =~ /\.pl$/;
    #...
    }

    If you want the count of the files, either keep track as you're
    reading them in, or read them into an array first and then get the
    count of that:
    my @files = glob("*.pl");
    my $count = @files;
    (or, as you found, bastardize the empty-list-assignment feature:
    my $count = () = glob("*.pl");
    )

    You'll note the context-based return value of glob() also matches the
    context-based return value of readdir(). All files in list context,
    "next" file in scalar context.

    > > You either have an old and/or broken version of Perldoc, or
    > > you oddly omitted a section. In my perldoc, there is another
    > > sentence between those two:

    >
    > Hmm, I'm using Perl 5.6.1 on RH Linux and it does seem to lack that
    > section:


    I'd call that a documentation bug in 5.6.1. I verified the same thing
    with a 5.6.1 version on solaris. The function works the same as it
    does on 5.8, but the docs lack that rather important note.

    > > Arrays evaluated in scalar context return their size. That's
    > > it. You cannot generalize "array" to "any expression returning
    > > a list." Any function returning a list of values in list
    > > context is free to do anything else in scalar context.

    >
    > Hmm, thanks for pointing that out. Yes it is easy to get into
    > that way of thinking, when many functions seem to return the
    > count (ie, map, grep) when used in scalar context.


    Oh, I agree. That's why I called it a trap. It gets easier to
    remember once you start writing your own subroutines that do something
    different depending on context, using the wantarray() function.

    > > If your version of perldoc really is missing that critical
    > > section, I suggest you check out the most recent version:
    > >http://perldoc.perl.org/functions/glob.html

    >
    > Thank you, I have saved this.


    You're welcome. Note that I generally recommend you use the version
    of the documentation that matches your version of Perl, but in this
    case, it's unfortunate that the docs themselves contain a bug..

    Paul Lalli
     
    Paul Lalli, Jun 28, 2007
    #14
  15. Paul Lalli wrote:
    > On Jun 28, 3:12 pm, "Clenna Lumina" <> wrote:
    >> Paul Lalli wrote:
    >>> On Jun 28, 2:49 pm, "Clenna Lumina" <>
    >>> wrote:

    >>
    >>>> Grep works fine. But I want to know why Glob returns the way
    >>>> it does in your original code?

    >>
    >>> Because glob() does something different depending on if its
    >>> called in scalar context or list context.

    >>
    >> Would it not of been more logical to have it return the count
    >> of the files it found, though?

    [...]
    > You'll note the context-based return value of glob() also matches the
    > context-based return value of readdir(). All files in list context,
    > "next" file in scalar context.


    Thought I still have to wonder if it wouldn't of been better for it to
    just behave like a normal list? I mean,

    for(@arr) { ... }

    iterates over the list.

    while(@arr) { ... }

    OTOH, gives you an infinite loop.

    Now that I think about it, that behavior (get next file) is a more
    useful, and would result in less memory usage. I guess the only
    potential gripe I see is that it behaves in a way you wouldn't expect
    the first time you used it.

    >>> You either have an old and/or broken version of Perldoc, or
    >>> you oddly omitted a section. In my perldoc, there is another
    >>> sentence between those two:

    >>
    >> Hmm, I'm using Perl 5.6.1 on RH Linux and it does seem to lack that
    >> section:

    >
    > I'd call that a documentation bug in 5.6.1. I verified the same thing
    > with a 5.6.1 version on solaris. The function works the same as it
    > does on 5.8, but the docs lack that rather important note.


    Good to know. Thanks.

    >>> Arrays evaluated in scalar context return their size. That's
    >>> it. You cannot generalize "array" to "any expression returning
    >>> a list." Any function returning a list of values in list
    >>> context is free to do anything else in scalar context.

    >>
    >> Hmm, thanks for pointing that out. Yes it is easy to get into
    >> that way of thinking, when many functions seem to return the
    >> count (ie, map, grep) when used in scalar context.

    >
    > Oh, I agree. That's why I called it a trap. It gets easier to
    > remember once you start writing your own subroutines that do something
    > different depending on context, using the wantarray() function.


    Yes I've seen many instances where it returns in a way you don't expect.
    Although most of the built in functions (sort, grep, map, ...) that
    return lists behave as you expect in scalar context too. 'grep' is
    commonly used as an 'if' conditional, for example.

    >>> If your version of perldoc really is missing that critical
    >>> section, I suggest you check out the most recent version:
    >>> http://perldoc.perl.org/functions/glob.html

    >>
    >> Thank you, I have saved this.

    >
    > You're welcome. Note that I generally recommend you use the version
    > of the documentation that matches your version of Perl, but in this
    > case, it's unfortunate that the docs themselves contain a bug..


    I know the people who maintain them do a good job and it's impossible to
    keep all of it up to date. I think it can be considered a lesson that
    there can always be more to something then just what's written.

    --
    CL
     
    Clenna Lumina, Jul 3, 2007
    #15
  16. On Tue, 3 Jul 2007 09:00:21 -0700, "Clenna Lumina"
    <> wrote:

    >Now that I think about it, that behavior (get next file) is a more
    >useful, and would result in less memory usage. I guess the only


    I'm not really sure: I may be wrong but ISTR that glob() reads all the
    entries behind the curtains anyway. Or there was some gotcha like
    that. If you can call it gotcha...

    >Yes I've seen many instances where it returns in a way you don't expect.
    >Although most of the built in functions (sort, grep, map, ...) that
    >return lists behave as you expect in scalar context too. 'grep' is
    >commonly used as an 'if' conditional, for example.


    ITYM within and if condition.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Jul 3, 2007
    #16
  17. Clenna Lumina <> wrote:

    > Although most of the built in functions (sort, grep, map, ...) that
    > return lists behave as you expect in scalar context too.



    You expected that sort() in a scalar context behaves
    in an undefined manner?


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad McClellan, Jul 4, 2007
    #17
  18. Tad McClellan wrote:
    > Clenna Lumina <> wrote:
    >
    >> Although most of the built in functions (sort, grep, map, ...) that
    >> return lists behave as you expect in scalar context too.

    >
    >
    > You expected that sort() in a scalar context behaves
    > in an undefined manner?


    Hmmm, I stand corrected. I ran some quick command-line tests, showing
    that 'map' and 'grep' return the item count but sort does not. It just
    seems to return undef:

    $ perl -le 'my @list = qw/1 2 4 8 16 32/; print(defined(scalar sort
    @list) ? "Y" : "N");'
    N

    Why is this?

    $ perldoc -f sort
    sort SUBNAME LIST
    sort BLOCK LIST
    sort LIST
    Sorts the LIST and returns the sorted list value.
    [...]

    It seems that it is supposed to be returning a list (assuming "list
    value", means that it's returning a list, which is the case in list
    context.) Having read through the whole article I can't seem to find a
    reason why it would returning undef. What use cold this possible have?
    Wouldn't it have been more logical to return the same was as 'map' and
    'grep' in scalar context?

    --
    CL
     
    Clenna Lumina, Jul 4, 2007
    #18
  19. Clenna Lumina <> wrote:
    > Tad McClellan wrote:
    >> Clenna Lumina <> wrote:
    >>
    >>> Although most of the built in functions (sort, grep, map, ...) that
    >>> return lists behave as you expect in scalar context too.

    >>
    >>
    >> You expected that sort() in a scalar context behaves
    >> in an undefined manner?

    >
    > Hmmm, I stand corrected. I ran some quick command-line tests, showing
    > that 'map' and 'grep' return the item count but sort does not. It just
    > seems to return undef:
    >
    > $ perl -le 'my @list = qw/1 2 4 8 16 32/; print(defined(scalar sort
    > @list) ? "Y" : "N");'
    > N
    >
    > Why is this?



    perldoc -f sort

    sort SUBNAME LIST
    sort BLOCK LIST
    sort LIST
    In list context, this sorts the LIST and returns the sorted list
    value. In scalar context, the behaviour of "sort()" is undeâ€
    fined.


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad McClellan, Jul 4, 2007
    #19
  20. Tad McClellan wrote:
    > Clenna Lumina <> wrote:
    >> Tad McClellan wrote:
    >>> Clenna Lumina <> wrote:
    >>>
    >>>> Although most of the built in functions (sort, grep, map, ...) that
    >>>> return lists behave as you expect in scalar context too.
    >>>
    >>>
    >>> You expected that sort() in a scalar context behaves
    >>> in an undefined manner?

    >>
    >> Hmmm, I stand corrected. I ran some quick command-line tests, showing
    >> that 'map' and 'grep' return the item count but sort does not. It
    >> just seems to return undef:
    >>
    >> $ perl -le 'my @list = qw/1 2 4 8 16 32/; print(defined(scalar
    >> sort @list) ? "Y" : "N");'
    >> N
    >>
    >> Why is this?

    >
    >
    > perldoc -f sort
    >
    > sort SUBNAME LIST
    > sort BLOCK LIST
    > sort LIST
    > In list context, this sorts the LIST and returns the
    > sorted list value. In scalar context, the behaviour of
    > "sort()" is undeâ? fined.


    I understand that it is undefined behavior, but what I'm trying to
    determine is what useful purpose could that possibly serve? Why doesn't
    it just return the count?

    (Note to self, update perldoc.)


    --
    CL
     
    Clenna Lumina, Jul 4, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Josh Martin
    Replies:
    6
    Views:
    1,861
    Josh Martin
    Nov 23, 2003
  2. Web learner
    Replies:
    0
    Views:
    745
    Web learner
    Apr 18, 2006
  3. Harlin Seritt

    Using wildcards...

    Harlin Seritt, May 2, 2005, in forum: Python
    Replies:
    4
    Views:
    364
    Harlin Seritt
    May 2, 2005
  4. Dipankar
    Replies:
    17
    Views:
    10,742
    Arne Vajhøj
    Aug 1, 2009
  5. William Hudspeth
    Replies:
    2
    Views:
    298
    Fabio FZero
    Mar 15, 2007
Loading...

Share This Page