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

Hi

Perl allows to open an file "abstraction" ° by providing a scalar-ref to a string

open FH, "<", \$str;

which is cool, because we can reuse all functionality based on reading files. Like with cached files.

see open#Opening-a-filehandle-into-an-in-memory-scalar for details.

But is there a way to do it with opendir ,too?

I did some experiments providing a scalarref, but with no avail.

like opendir DH, \$str

Since telldir returns an integer-positions, I suppose the input has to be a scalar text with line delimiters and not an array.

Motivation

DISCLAIMER: Since I'm not very optimistic about an existing solution, this should probably rather be a meditation (?)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

°) dunno how to phrase it better

Replies are listed 'Best First'.
Re: opendir a directory abstraction?
by Corion (Patriarch) on Feb 14, 2021 at 08:54 UTC

    There is Filesys::Virtual (and its subclasses), but I think not even that supports readdir on itself.

    I'm not sure a string would be a good approach as an API. I would expect more something like a tied FH, calling various methods on the tied object to return directory entries. But so far, I have not seen a good abstraction for filesystems.

      > Filesys::Virtual

      does it implement anything? I looked into the code b/c of missing documentation and all subs look like this

      sub login { my ($self, $username, $password) = @_; carp ref($self)."::login() Unimplemented"; return 0; }

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re: opendir a directory abstraction?
by salva (Canon) on Feb 14, 2021 at 08:38 UTC
    secondary: Powershell has some cool features based on directory abstraction of recursive structures, like cd registry-key and navigating it like a filesystem.
    IMO, the ideal approach for that would be to have a virtual file system layer, something that would allow one to hook his code into any function related to browsing the file structure. For instance, GNOME has GVfs for that.

    Actually, I think porting Perl to work on top of GVfs, could be an interesting project.

    primary: this question "glob an array?" would be trivial if we could chdir DH to a directory-handle which abstracts an array and glob it

    Note that glob under the hood is loading and calling File::Glob, and if you study the code for this module you will see it already has hooks in place to support user defined opendir, readdir and closedir operations. But then, those hooks are not exposed at the Perl level!

    Then you also have Text::Glob.

Re: opendir a directory abstraction?
by jcb (Parson) on Feb 14, 2021 at 03:24 UTC
    But is there a way to do it with opendir ,too?

    No; the ability to open a variable as a file is derived from PerlIO (and is only available if your perl was built with PerlIO, which has been default since 5.8) and PerlIO only handles byte-streams and not directory-streams. On a related note, you cannot tie directory handles either when I last checked.

    $ perl -e '$str="foo";' \
           -e 'open FH, "<", \$str or die "open: $!";' \
           -e 'print "var:   ",join(":",PerlIO::get_layers(FH)),"\n";' \
           -e 'print "STDIN: ",join(":",PerlIO::get_layers(STDIN)),"\n";'
    var:   scalar
    STDIN: unix:perlio
    
Re: opendir a directory abstraction?
by jwkrahn (Abbot) on Feb 13, 2021 at 15:00 UTC

    I assume that you would have to have some way to specify what file system the directory entries in your string are based on?   Or would you assume that they are the same as the root file system?

    And what would the inode numbers point to?

      > I assume that you would have to have some way to specify what file system the directory entries in your string are based on?

      No, rather a minimal abstraction of a file system.

      Kind of a nested data-structure like a AoA or HoH, not the full implementation.

      > And what would the inode numbers point to?

      nowhere? stat doesn't work on abstracted FH either, hence no "inode"

      DB<410> $str = join "\n", a..d DB<411> open AFH, "<",\$str DB<412> p "".<AFH> a DB<413> p "".<AFH> b DB<414> @stat = stat AFH DB<415> x @stat empty array DB<416>

      see also stat: "Not all fields are supported on all filesystem types."

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery