Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dealing with Files #9

Open
kentfredric opened this issue Sep 20, 2013 · 11 comments
Open

Dealing with Files #9

kentfredric opened this issue Sep 20, 2013 · 11 comments

Comments

@kentfredric
Copy link
Collaborator

Path::Tiny

( Which is an improved reductionist lightweight alternative to Path::Class, does everything Path::Class does, does it better, )

Path::Iterator::Rule

( Which is more or less a hugely improved reductionist take on File::Find::Rule )

File::Next

ack-grep

@kentfredric
Copy link
Collaborator Author

I personally think File::Next should be missed, its surely one of the fastest, but the API is a little wonky and hard to cognitively memoize.

And I can't seem to imagine anything you could do with it that wouldn't be easier to do with either Path::Tiny or Path::Iterator::Rule

ie:

use Path::Tiny qw(path);
my $iterator = path('/some/path')->iterator({ recurse => 1 });
while( my $item = $iterator->() ) { 
  # . and .. automatically skipped for you
  # walks entire /some/path and each item is a Path::Tiny object 
}

And for more complex things theres Path::Iterator::Rule, which shares the same familiar API style

use Path::Iterator::Rule;
my $rule = Path::Iterator::Rule->new->file;
my $iterator = $rule->iter("/some/path");
while( my $item = $iterator->() ) { 
  # . and .. automatically skipped for you
  # walks entire /some/path and each item is a string
  # also, as per rule above, only files are returned to user
}

@jjl
Copy link
Owner

jjl commented Sep 21, 2013

File::Next looked promising with files(), dirs() and everything(). Then I read it has loads more stuff and started facepalming. Path::Tiny one should be modified with next unless $item->is_file;, partially because the documentation doesn't indicate it skips directories (I'm not saying you're wrong, I haven't read the code), but because we can replace the $item->is_file with next unless is_wanted_item($item) and then it becomes very much more reusable in the context of doing ever more impressive things.

It might be great to team it with IO::All, which is damn cool. Python has now gotten much cleaner for dealing with files as well, but IO::All still definitely has the edge.

with open(filename) as fh:
    for line in fh:
        func(line)

This then takes care of closure of the file the moment the block has been left. What's quite nifty is that this doesn't just apply to files, but the syntax extends to quite of lot of things. I wonder if we could extended the ideas of IO::All onwards in a similar manner.

@jjl jjl closed this as completed Sep 21, 2013
@jjl jjl reopened this Sep 21, 2013
@jjl
Copy link
Owner

jjl commented Sep 21, 2013

Sorry, didn't mean to hit close. I've been doing that too much during the daytime recently.

@osfameron
Copy link
Collaborator

re with-open-file, we can already do:

for my $fh (io 'foo.dot') {
    for my $line ($fh->getlines) {
    print $line;
    }
}

Or we could hack up a 'with' keyword using Keywords::API or similar that does same as for, but in scalar context.

@davorg
Copy link
Collaborator

davorg commented Sep 21, 2013

IO::All scares the crap out of me. I place it firmly in the "too magic to be used in production" category. I really wouldn't be introducing it to beginners.

@jjl
Copy link
Owner

jjl commented Sep 21, 2013

Are we really targeting beginners though? Perhaps people who don't know too much perl, but generally I think we're targeted at people who know how to code to at least some standard.

@jjl
Copy link
Owner

jjl commented Sep 21, 2013

What about an IO::Most wrapper around IO::All that removes a bit of the crack (and things that aren't useful to most people anyway) ?

@jjl
Copy link
Owner

jjl commented Sep 21, 2013

osf': isn't that equivalent to:

{
  my $fh = io "foo.bar";
  ...
}

@osfameron
Copy link
Collaborator

jjl sure, that's pretty much all a with statement is, isn't it? Create scope, bind a variable within that scope.

Using a for keyword just has the benefit that it can do the aliasing to $_ if you prefer, and it's more explicitly setting a variable then the bare block (using a 'with' keyword would be even clearer).

@kentfredric
Copy link
Collaborator Author

I don't use IO::All, its just far too "magical" for me.

my $fh = path("/some/path")->openr; 

Is adequate, explicit, and unambiguous.

And for linewise,

for my $line ( path("/some/path")->lines ) {

}

And if you want the lines chomped

for my $line ( path("/some/path")->lines({ chomp => 1 }) ) {

}

And if you want utf8

for my $line ( path("/some/path")->lines_utf8({ chomp => 1 }) ) {

}

Just more "natural" to me than most the IO::All magic.

@kentfredric
Copy link
Collaborator Author

"partially because the documentation doesn't indicate it skips directories "

And yes, Path::Tiny's recursive iterator tool traveses both files and directories, returning both.

As does Path::Iterator::Rule unless you tell it to reduce results to files by specifying the ->file rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants