Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

diamond operator question

by Tomtom (Scribe)
on Jun 09, 2005 at 07:56 UTC ( [id://464995]=perlquestion: print w/replies, xml ) Need Help??

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

Hello everyone,

I know that the diamond operator reads lines ( one line in scalar context, and all lines in a list context ) from a file.
On the other hand, I read this :
"A directory is actually implemented as a file that has one line for each item contained within the directory."
from here (although I remember reading this somewhere else too).

I was wondering why, since directories are considered being "the same" as files on UNIX systems, the diamond operator doesn't work on directories.
I'm not sure, but doesn't the diamond operator call readline for a file ?
Why doesn't it call readdir for a directory ?

Replies are listed 'Best First'.
Re: diamond operator question
by muntfish (Chaplain) on Jun 09, 2005 at 08:38 UTC

    A Unix directory may be implemented as a file with one entry per file, but that doesn't necessarily equate to one line of a text file. The precise format of the file is a low-level implementation detail and I doubt it would be the same on all variants of Unix. If I type cat . on HP-UX I just get gibberish, containing recognisable filenames plus a load of binary stuff - and no line-ends.


    s^^unp(;75N=&9I<V@`ack(u,^;s|\(.+\`|"$`$'\"$&\"\)"|ee;/m.+h/&&print$&
      Is there a reason why the diamond operator in Perl doesn't call readdir for directories, the same way it calls readline for regular files ?

        I suppose they could have done that, but I can't comment on why they didn't. It would have to be able to detect whether it was working on a filehandle created by open or a dir handle created by opendir, but I guess that's not unreasonable.


        s^^unp(;75N=&9I<V@`ack(u,^;s|\(.+\`|"$`$'\"$&\"\)"|ee;/m.+h/&&print$&

        Orthagonality with the C opendir(2) and friends would be my guess. If it really mattered to you you probably could implement a tied filehandle that provided its own map from readline to readdir without too much trouble.

        Update: Yeah, not too much trouble at all.

        #!/usr/bin/perl use strict; package Tie::Dirfile; use IO::Dir (); sub TIEHANDLE { my $class = shift; my $self = {}; $self->{_dir} = shift; $self->{_handle} = IO::Dir->new( $self->{_dir} ); return bless $self, $class; } sub READLINE { return shift()->{_handle}->read; } sub CLOSE { return shift()->{_handle}->close( ); } package main; local( *DH ); tie *DH, 'Tie::Dirfile' => "/bin" or die "Can't create Tie::Dirfile for /bin: $!\n"; my $i = 0; print $i++, ": ", $_, "\n" while( <DH> ); close( DH ); exit 0; __END__

        --
        We're looking for people in ATL

Re: diamond operator question
by ambrus (Abbot) on Jun 09, 2005 at 10:17 UTC

    They're not considered the same.

    We have the higher-level opendir(3), readdir(3), closedir(3) etc functions in libc exactly because directories are not treated uniformly between UNIX systems.

    For example, in Linux systems, you can not actually read directories. You can open them, but if you try to read them, you get EISDIR. The way readdir reads them is the SysV function getdents (and its lfs equivalent, getdents64).

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-24 18:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found