9

Is there an alternate way in perl6 to get file attribute details like size, access_time, modified_time.. etc. without having to invoke native call?

As per the doc it is "unlikely to be implemented as a built in as its POSIX specific".

What workaround options are available excluding the system call to stat?

Any ideas or pointers are much appreciated.

Thanks.

Borodin
  • 126,100
  • 9
  • 70
  • 144
User9102d82
  • 1,172
  • 9
  • 19
  • 2
    Perhaps https://modules.perl6.org/dist/P5-X can be of service? – Elizabeth Mattijsen Aug 29 '18 at 17:11
  • 1
    I have to say this seems doable. In fact this might be the alternative I may have been looking for. But I am very surprised that stat is not being provided as a built in. I will check the module and come back with results. At the moment zef throws error when I try to install any module. I am yet to fix that. – User9102d82 Aug 29 '18 at 17:22
  • This is unfortunate and is an indication of how perl6 has gone astray. In his first Apocalypse, Larry Wall said that perl5 and perl6 should be different syntaxes on top of the same underlying execution model. perl5 implements `stat` portably without the user needing to write system-specific native calls, and so Perl6 can and should provide the same functionality, but it doesn't -- e.g., IO::Path doesn't provide the `blocks` field, which I happen to need. One of the great values of perl5 is that it provides POSIX functionality even on non-POSIX systems. The perl6 turkeys broke that. – Jim Balter Aug 22 '19 at 23:01

2 Answers2

11

See the IO::Path doc.

For example:

say 'foo'.IO.s; # 3 if 'foo' is an existing file of size 3 bytes

.IO on a string creates an IO::Path object corresponding to the filesystem entry corresponding to the path given by the string.

See examples of using junctions to get multiple attributes at the same time at the doc on ACCEPTS.


I'm not sure if the following is too much. Ignore it if it is. Hopefully it's helpful.

You can discover/explore some of what's available in Perl 6 via its HOW objects (aka Higher Order Workings objects, How Objects Work objects, metaobjects -- whatever you want to call them) which know HOW objects of a particular type work.

say IO::Path.^methods

displays:

(BUILD new is-absolute is-relative parts volume dirname basename extension
 Numeric sibling succ pred open watch absolute relative cleanup resolve
 parent child add chdir rename copy move chmod unlink symlink link mkdir
 rmdir dir slurp spurt lines comb split words e d f s l r w rw x rwx z
 modified accessed changed mode ACCEPTS Str gist perl IO SPEC CWD path BUILDALL)

Those are some of the methods available on an IO::Path object.

(You can get more or less with adverbs, eg. say IO::Path.^methods(:all), but the default display aims at giving you the ones you're likely most interested in. The up arrow (^) means the method call (.methods) is not sent to the invocant but rather is sent "upwards", up to its HOW object as explained above.)

Here's an example of applying some of them one at a time:

spurt 'foo', 'bar'; # write a three letter string to a file called 'foo'. 
for <e d f s l r w rw x rwx z modified accessed changed mode>
  -> $method { say 'foo'.IO."$method"() }

The second line does a for loop over the methods listed by their string names in the <...> construct. To call a method on an invocant given it's name in a variable $qux, write ."$qux"(...).

raiph
  • 31,607
  • 3
  • 62
  • 111
  • 5
    I believe this is what I was looking for but didn't know about it. I really appreciate you taking time to equip me with this information. Your explanation of how to know what methods does a function offer, was most helpful. I can now check list of methods a function has to offer, with ease. Tried it out on the command line and its fantastic. Thanks raiph. – User9102d82 Aug 29 '18 at 18:23
  • 1
    NB. My tip is just for methods. Many routines are available in either of the two main routine forms (`method`s and `sub`s). Many others are just one or other. You might discover, say, `.say` by looking at methods available on [`Mu`](https://docs.perl6.org/type/Mu) ([Mu](https://en.wikipedia.org/wiki/Mu_(negative)) has a Zen buddhism meaning of being the nothing from which everything springs). Then try `say foo` and discover there's a `sub` form of `say` too. But to discover variables, and `sub` only routines that aren't methods, you have to look in [Stash](https://docs.perl6.org/type/Stash)es. – raiph Aug 29 '18 at 18:36
  • I was unaware of the distinction between method and sub in perl6. I need to study this one. This is "new stuff" ;). – User9102d82 Aug 30 '18 at 15:44
  • Interesting. Are you familiar with them in P5? I think only `sub` is available straight out of the box with P5's interpreter but a `method` declarator is available via various OO subsystems that are available on [CPAN](https://metacpan.org/) to be `use`d. (Do you know about CPAN?) These OO subsystems are vast continents of functionality that add very powerful keywords and features to Perl. Many are part of a decade old family called Moose, Mouse, Moo, etc. with thousands, perhaps tens of thousands, of modules they add to P5. P6 bakes in default OO and can use the P5 OO modules as well. – raiph Aug 30 '18 at 20:16
1

While looking for an answer to this question in 2021, there is the File::Stat module. It provides some additional stat(2) information such as UID, GID and mode.

#!/usr/bin/env raku
use File::Stat <stat>;
say File::Stat.new(path => $?FILE).mode.base(8);
say stat($?FILE).uid;
say stat($?FILE).gid;
Norman Gaywood
  • 357
  • 2
  • 7