schwern / perl5i
- Source
- Commits
- Network (14)
- Issues (40)
- Downloads (1)
- Wiki (1)
- Graphs
-
Branch:
master
-
Document the existence of the perl5i utility in the module and also provide some POD in the thing itself.
Comments
-
1 comment Created 6 months ago by schwernlocaltime is very slow with a distant dateperformancexIt looks like the slowness is in DateTime->set_time_zone(). It starts to get noticeably slower after 2038.
Comments
Tracked this down to a very inefficient DateTime::TimeZone.
https://rt.cpan.org/Ticket/Display.html?id=47671 -
4 comments Created 8 months ago by schwernSomething to make system calls easierwishlistxAdd something to smooth out cross platform issues with running programs.
IPC::Cmd? IPC::Run?
Comments
Since you're already using autodie qw(:all), perl5i will be delegating the heavy lifting of system() to IPC::System::Simple. It also provides a capture() method that isn't exported by autodie, but which does provide a cross-platform replacement for backticks.
IPC::System::Simple goes to great lengths to smooth out cross-platform issues. In particular, it detects and corrects all sorts of wacky bugs, like windows running commands twice, or not running them at all and saying that it did, or Perl 5.10 under Linux not reporting coredumps, or older versions of Perl not doing proper taint checking.
Of course, IPC::System::Simple only provides you with a simple interface. If you want anything more than that, you'll need to use a different module.
-- Paul
IPC::System::Simple tries very hard to be as close as possible in syntax and semantics to system() and backticks without sucking; that's why it's got 'simple' in the name.
Capturing STDERR is something which has come up a few times. There aren't any technical barriers to doing it, but there are interface barriers. Unless you want something that just rolls STDOUT and STDERR together, then it's easy to end up with an interface that's large and complex, which is very much against the IPC::System::Simple design goal.
Interface suggestions are very welcome. If it's simple, clean, and can be used by a developer who has the attention span of a monkey chewing on a fly-swatter, then I'm very willing to consider it.
I'm also interested if you find the holy grail of IPC modules, which works consistently everywhere, has an interface that doesn't suck, doesn't require me to look inside $?, returns full return values on Windows, doesn't use the shell when it's not supposed to, captures both stdout and stderr, performs taint checks, looks up signal names, and throws proper exception objects, then do let me know. ;)
I think I've implemented helpers for IPC::Open3 methods 3 times in 3 different ways. I'm pretty happy with my latest iteration of this if we'd like to go down an open3 route. Accepts an arrayref of command+args and returns stdout & stderr as scalars. Could also implement returning the system return value/pid etc.
The method I'm using currently is probably a reworking of some part of IPC::Run(tweaked what I needed w/out installing the module). Have not given any thought to portability with the method though.
-
6 comments Created 8 months ago by schwernMake system() return a true value on success, false on failurewishlistxUse an overloaded object which boolifies to true/false but numifies to the exit code. This will let if( system("...") ) work but also let if( system("...") == 0 ) still work.
Comments
That looks as easy as overriding system with
use Scalar::Util qw/dualvar/;
sub system {
my $ret = CORE::system @_; return dualvar $ret, $ret == 0;}
Do you want that in perl5i or as a separate module?
dualvar isn't going to cut it. The exit code won't show up in string context, like when it gets printed.
$ perl -wle 'print system "dont exist"' Can't exec "dont": No such file or directory at -e line 1.
-1$ perl -wle 'use Scalar::Util qw/dualvar/; sub system { my $ret = CORE::system(@_); return dualvar($ret, $ret == 0) } print ::system("dont exist")' Can't exec "dont": No such file or directory at -e line 1.
Okay, it isn't fully tested (because I have to sleep at somepoint), but how about this:
Hang on, we're already using autodie qw(:all), aren't we? That means that system already throws an exception on failure, and returns the command's exit value on success.
By default, non-zero exit statuses are considered a failure (and result in an exception). You can supply a list of "successful" exit values as the first argument:
system( [0, 1], $cmd, @args); # exit value of 2+ is considered a failure.
As a special case, you can pass in a value of [ -1 ] to mean that any exit value is considered okay:
my $exit_value = system( [ -1 ], $cmd, @args);
Cheerio,
Paul
@cowens For future reference, you want to use the "fallback" parameter to overload. Then you only have to implement 0+ and Perl will figure out the rest.
@pjf INGENIOUS! Teach me not to write tests first. Hmm, doesn't look like the exit code is in the exception. Could you add a way to get at that?
The inability to get the exit status and other information is a known bug, and already on my TODO list. It involves a modest rearchitecture of the underlying IPC::System::Simple module to improve its error reporting.
I've actually got a rough design spec put together for the changes needed, and while I've discussed this with @jettero, I should publish it in a more public place to make it easier for patches to find me. ;)
This weekend has me working on autodie's hinting interface as a first priority, to make sure it's ready in time for everyone to feel comfortable about it for the 5.10.1 release. If I get the time I'd love to get the ISS fixes done at the same time, but that depends very much on my supply of round tuits.
-
1 comment Created 8 months ago by schwernSomething to make files and directories easierwishlistx -
MooseX::Declare is sexy. It also solves the problem of Moose load time since it can lazy load when class() is called.
Comments
supernovus
Thu Dec 03 16:36:56 -0800 2009
| link
I have found that the recent versions of MooseX::Declare itself adds at least 1 second to the compile time of a program. Therefore, I have made it an optional feature in my own fork of perl5i. A quick 'use perl5i moose => 1;' will enable it in the global level.
Then in your class myclass { statement you need to include 'use perl5i' again (without the moose => 1 this time) as I haven't figured out how to make that automatically get added to the class and role statements. If anyone knows, please feel free to fork and fix!
-
Somehow integrate local::lib to solve the problem of locally installed modules
Comments
-
3 comments Created 8 months ago by schwernObjects and references in hash keyswishlistxJesse Wolfe is annoyed that he can't put objects/references in hash keys. I don't know if there's a way to do this without patching core, but it sure would be nice
Comments
use Tie::RefHash::Nestable by default unless specified otherwise?
But fixing it in core would be better, certainly.
Putting aside for a moment the performance problems, how would one tie all hashes "by default"?
Adding some kind of hack to make all hashes Tie::RefHash::Nestable, unless and until tied to a different class, would be one ugly way to provide this behaviour. (For example a source filter that turns "my %h;" into 'my %h; tie %h, "Tie::RefHash::Nestable" or die;'
But as I mentioned I think it would be better to fix core to preserve references stored in hash keys.
-
We needs some. Carp is the obvious choice. Is there a better one?
Comments
-
touch
recursive rm
mv and cp allowing multiple source files to a directory
mkdir -p
Crib from ExtUtils::Command and Shell::Command.
Comments
Is this too UNIX centric?
Recursive
rmandmkdir -palready exist inFile::Pathasremove_treeandmkpathrespectively. Multiple file mv and copy should be easy: move and copy from File::Copy combined with a for loop.sub mv { my $dir = pop; croak "not enough args" unless @_; for my $file (@_) { move $file, $dir or croak "could not move '$file' to '$dir': $!; } return 1; }touchis implemented byTouchThe names are Unixy, but the need for the functionality is not. make_path() and remove_tree() are better. Not sure what to do about mv and cp and touch.
-
Would it be helpful to automatically use mylib to have an absolute path to /path/which/contains/program/lib ?
Comments
I would classify that as unexpected, unpleasant behaviour.
It prepends directories I didn't specify to @INC, messing with @INC behind my back is not nice. Everything else in perl5i (except strict, which is a special case) has enhanced existing things. You could ignore the enhancements if you wanted to. But with mylib I would have to worry that the directory my script is in (or its parent directory) might have a lib directory and the lib directory might have a .pm or .pmc file that matches a module I am using. Imagine helper scripts in a source directory that use the installed version of the module, suddenly they will use the new (possibly buggy) version of the module instead of the installed version (which presumably has been tested). Also, I have to take extra pains to not have it prepend stuff (e.g. shifting @INC in a BEGIN block after use perl5i).
Thanks for expanding on that.
Part of perl5i is to make Perl DTRT for 99% of the cases and only for the remaining 1% do you have to turn it off. To that end, for every scenario where you have a module in lib/ and you don't want to use it I'm pretty sure there's about 100 where you do. Since the @INC path is absolute it's not nearly as dangerous as, say, having the cwd in @INC which we already do and the sky remains fixed firmly overhead.
You're right that having to muck with @INC in a BEGIN block to turn it off is ugly. I think a "no mylib" would allow those 1% to easily turn off the behavior.
There is one scenario where its a bad idea, and that's in module testing since that wants to use blib, not lib. That's a pretty broad case. It might make sense to prepend blib/lib as well, but then I'm wondering if that's a bit too much of a good thing.
But is using ./lib the right thing? Is this something we want to encourage people to do? Or would we rather people use
Module::Starterto make installable modules and have them install the modules into the right place (rather than some random place). If we are talking about delivering projects that are supposed to be self-contained, well, that is what PAR is for.Including mylib doesn't eliminate any of that. And they're all relatively complicated things that have to be discovered and configured and learned by both the developer and the user. Shipping a program as a module is often overkill, your users have to understand the Perl module installation process just to get their program running. PAR is neat, but it creates opaque files which are difficult to debug.
As I use more and more PHP there's definite value in being able to just unpack a source archive and have it work. So to the question of whether this is the sort of thing we want to encourage people to do I say yes.
-
Like stat() and localtime()
Comments
supernovus
Thu Dec 03 11:39:17 -0800 2009
| link
There is Perl6::Caller which provides behavior similar to what you are looking for. It would probably be fairly simple to integrate it with perl5i. I don't have any experience with github (just signed up) but I could look at implementing that change.
supernovus
Thu Dec 03 16:33:36 -0800 2009
| link
And, again, in my own fork I have implemented Perl6::Caller as an automatically included module.
-
0 comments Created 7 months ago by schwernDo something to fix all the functions which deal with getting user and group informationwishlistxAll that getpwuid and junk.
Comments
-
5 comments Created 6 months ago by schwernSomething to make reading and writing files easier.wishlistxFile::Slurp is the obvious candidate. I also like that it can write_file() in one go.
Perl6::Slurp is far more complete, but it doesn't write files, its way more complicated and its scary, old, unmaintained Damian-ware. Perhaps the solution is to enhance File::Slurp with Perl6::Slurp features.
Finally, a solution to the "how do I insert a line in the middle of a file" would be nice. That can be served by the excellent and efficient Tie::File but with a sprinkling of sugar so the user isn't exposed to a tie() call. They just get an array (or array ref or object acting like an array ref).
Comments
In addition to insertion, replacing a line in the middle of a file using Tie::File is something I do frequently, and is one task for which I'd like some sugar. Something like
file( 'foo.txt' )->replace_line( 'service foo-0' => 'service bar-0' );
would be great.
IO::All has Tie::File sugar.
$io = io 'file.txt'; $io->[42] = 'Line Forty Three'; # Change a line print $io->[@$io / 2]; # Print middle line @$io = reverse @$io; # Reverse the file $_ =~ s/this/that/ for @$io; # s/// over the whole file
supernovus
Thu Dec 03 11:41:16 -0800 2009
| link
I second IO::All, it's very slick, and really does live up to it's name!
supernovus
Thu Dec 03 16:32:26 -0800 2009
| link
And since I liked it, I added it to my own fork. Enjoy!
-
This thing is going to get pretty fat pretty fast. It would be nice if it delayed loading of modules for as long as possible.
Things like File::stat and Time::Piece that only export a handful of functions can be wrapped in autoloading functions. Just benchmark before hand to see if it helps load time to actually remove them. A lot of the cost of loading a module in isolation is actually loading very common modules (strict, Exporter, base...) which will be loaded anyway.
Comments
-
alias my $foo => \$bar;would be spiffy. Data::Alias would do that, but its kinda broken on bleadperl.Comments
-
0 comments Created 6 months ago by schwerngmtime() and localtime() crap out around y5872869bugxAnd they don't warn!
$ time perl -wle 'use perl5i; print scalar gmtime 2**48-2**46-2**45+2**44-2**43+2**42-2**41-2**40'Mon Jan 3 06:09:04 -5868930$ time perl -wle 'use perl5i; print scalar gmtime 2**48-2**46-2**45+2**44-2**43+2**42-2**41-2**40-2**39'Sat Dec 28 17:50:56 5872869Comments
-
Might it be handy to load that? Maybe make %RE load Regexp::Common on demand.
Comments
-
Though some of the method names could use some work. Like natatime().
uniq, zip, any, all, none, true, false are all nice.
Comments
-
0 comments Created 6 months ago by schwernSomething to allow you to change $_ to a real variable in blockswishlistxLike in Ruby.
@foo = map { |$var| $var++ } @bar;to be equivalent to
@foo = map { $_++ } @bar;Perhaps using Data::Bind?
Comments
-
0 comments Created 6 months ago by schwernFunctions with blocks attached to them.wishlistxLike in Ruby.
read $file { print; }Comments
-
A replacement for $self->SUPER::method(@args) would be $self->super(@args);
Comments
-
An improved configuration for the CPAN shell. It will ask one question "do you want to install for yourself or for the whole system" and then configure everything for you. Then it will ask "do you want detailed configuration?" with a default of "no". That's it. You will have a working, configured CPAN shell.
Comments
-
Much of perl5i is not lexical. Muck with %^H to make it so. Tests in t/lexical.t
Comments
-
0 comments Created 6 months ago by schwernA foreach iterator for hashes / tuples / pairswishlistxInstead of
for my $key (keys %hash) { my $value = $hash{$key}; .... }I want
for my($key, $value) (%hash) { ... }Or something. Also working for pairs in lists. Extend it out to work for any number of elements.
Comments
-
Stuff for merging hashes and flattening hashes.
Comments
Look at the PHP array functions for inspiration.
http://php.net/manual/en/function.array.php -
trim (strip whitespace), ltrim, rtrim
is a number
is an integer, decimal... all the stuff from perlfaq4is a regex
is an object/instance
is a reference
Comments
-
It might be a good idea to have a source filter to change
local @CWD;into
local $CWD;or at least throw a warning.
Comments
-
1 comment Created 6 months ago by cowenscarp and croak should be always be availablewishlistxWe should make them functions in perl5i that load Carp if it hasn't already and call carp or croak (after adding the "at FILE line LINE" if the message doesn't end in "\n"). Might be a good idea to have a backtrace function as well.
Comments
supernovus
Thu Dec 03 16:30:19 -0800 2009
| link
Well, in my fork, I have just added Carp to the list of imported modules (as well as several other features.)
If you are interested, you can see my fork over here. Maybe it it's useful, it'll get merged with the original version. -
0 comments Created 6 months ago by schwernSomething to handle string encodingwishlistxIt would be handy if we had something to deal with string encoding issues. UTF8 and whatnot. jokke started in on it. http://github.com/joakiml/perl5i/commit/68ec98603e78f7e1d861f7f529457237c11a59b2#diff-0
There's also autobox::Encode.
The terminology will have to be reviewed. "encode" and "decode" are too general, there's lots of things which "encode" that have nothing to do with character formats. They're also confusing. "encode" does not immediately imply "convert from Perl's internal format to a string of octets in the given format".
Comments
-
Every time ./Build is run bin/perl5i is rebuilt. This should ideally be fixed by moving the building of bin/perl5i into its own ACTION and making that action depend on bin/perl5i.c being newer than bin/perl5i.
In make parlance...
bin/perl5i: bin/perl5i.c ...compile bin/perl5i... bin/perl5i.c: bin/perl5i.c.PL ...run perl5i.c.PL to make perl5i.c... build: bin/perl5iComments
-
Stabilty, experimentation, change and versioning
0 comments Created 5 months ago by schwernperl5i has to provide both stabilty, so it can be used in production without having to rewrite your code every release, as well as continuing ability to experiment including breaking compatibility with itself. This is the paradox Perl 5 finds itself in.
To support this it has been proposed that perl5i use an X.Y.Z versioning scheme. A change in X indicates a deliberately incompatible change which breaks a documented feature. Y is for new features (adding new methods and functionality). Z is for bug fixes.
Then users can write "use perl5i as => 5" which causes perl5i to act like version 5.Y.Z. This "version stapling", as I've been calling it, lets one use perl5i guaranteeing stability while allowing us to still change things.
An implementation would be to have perl5i.pm be nothing more than an import() routine which selects the proper version. The rest of the distribution is under lib/perl5i/$X/. Each $X directory contains a complete copy of the distribution. This will avoid having to write lots of "if version X do this, else if version Y do this, else if version Z do this" code. It allows older versions to simply fade away.
The downside of that approach is A) we need to ship all the old versions, and depend on their dependencies, which could get rather large, B) we can't use cherry-pick to pull bug fixes from one major version to another.
An alternative would be a syntax like "use perl5i::5". This would do the same as the above, but then users can depend on perl5i::5, it can be split off into its own distribution once it's stable (ie. dead) and branch. Doesn't solve the cherry picking problem.
More specific version numbers like "use perl5i as => 5.2" will probably not be supported as keeping them all in line will be difficult.
Either way, if we do this the current version on CPAN will have to be pulled and a nasty version sheer will occur for anyone who already has it installed necessitating a manual update. I'm willing to live with that this early in the project for the benefit.
Comments
-
I often have to wade through pages of info to find the little
pertinent bits scattered throughout. It would be nice if we could
somehow improve the signal-to-noise ratio while at the same time
keeping the syntax terse. I'm not entirely sure if this is possible or
practical.A couple of examples:
I have a huge datastructure/object and I only want to see some
portion(s) of it.I do a trace but its huge and I'm only looking for a few of the frames.
Dumping:
For the dumping I'm thinking maybe having views on types. Where there
cab be a custom set of dumping views for a type and there's a default set.
These views would allow for selecting subsets maybe by using something
like Data::DPath. Looks like Data::DPath doesn't allow custom filters.
But if that were made possible then we could do searching and filtering
with a fairly tight syntax. It might look something like this:RandomType->dump( "/foo/*[ attrs ]" );
Tracing:
For the tracing I think just a grep-like filter with a terse syntax could
work fine. It could look like this:trace( qr/SomethingIWantToSee/ );
And maybe the stack level could be added to the trace to make it easy
to know how much of the trace was filtered out as well as where the
remaining frames were.UPDATE (7/16/09):
In fact I think starting each frame on its own line with the depth would even be an
improvement.Comments
-
An easy way to create DateTime objects from common "date/time-ish" strings
0 comments Created 5 months ago by cfeddemy $d = timestamp('07/08/09'); # speaks DWIMish, locale sensitive
say $d + 45->days;
say $d->next_workday;
say $d->last('tuesday');
say ($d - now->next('friday')->days; # signed fractional days betweenbla bla bla
Comments
-
0 comments Created 5 months ago by schwernTurn off strict vars when writing a one-linerwishlistxWriting one liners with perl5i is a little annoying because it wants me to predeclare all my variables. Strict is on. I think that's a little silly. If $0 is -e turn strict vars off. Leave the rest on.
Comments
-
Most OO systems have some sort of top level "Object" class from which everything inherits. Perl has UNIVERSAL but the general consensus is OH GOD DON'T PUT ANYTHING IN UNIVERSAL!!! The arguments are generally that its unexpected and what people put in is random and 2 modules might try to put the same method in and clash.
perl5i can coordinate what goes into Object so that eliminates the coordination and unexpected issues (well, you might not expect perl5i to do that, but that's another story).
And as for the name "UNIVERSAL" well...
package UNIVERSAL; @ISA = qw(Object);heh
Comments
-
Correct process names on all platforms so killall works.
0 comments Created 4 months ago by tlbdkI have the Linux part working:
http://search.cpan.org/~tlbdk/Sys-Prctl-1.00/lib/Sys/Prctl.pmComments
-
Get some IO error signals to throw exceptions instead of uncatchable warnings
0 comments Created 4 months ago by tlbdkNeeded when writing to a broken pipe
$SIG{PIPE} = sub { # SIGPIPE
croak "Broken pipe";};
Needed as sysread() throws warnings when STDIN gets closed by the child
$SIG{WARN} = sub {
croak @_;};
Comments
-
Dealing with eval and $@ is not only ugly, but is seldom done right (ie, with proper localization of $@; for more on why, see http://blog.woobling.org/2009/09/trytiny.html).
>Among the exception handling modules, the recently created Try::Tiny is an attractive choice for its low overhead cost, minimalism, correctness and lack of dependencies.
I think it would be worth it to add try/catch semantics to perl5i using Try::Tiny. I implemented this addition in my fork of the project, only awaiting for a thumbs up and a merge.
Comments
supernovus
Thu Dec 03 16:31:09 -0800 2009
| link
I have forked brunoV's fork and added some extra features if anyone is interested.
- bug▾
- docs▾
- needs eyes▾
- performance▾
- tests▾
- wishlist▾
- yes, do it▾
- Apply to Selection
-
Change Color…
Preview:preview
- Rename…
- Delete





Implemented in SHA: 456e584 by Darian Anthony Patrick dap@darianpatrick.com
Thanks. I was just about to make the same note.
Whoops, perldoc picks up the perl5i program before the perl5i file. dap tried to warn me of this, but I thought it was the reverse. There's a work around, "perldoc perl5i.pm", but that's annoying. Don't know what to do about that.
I think the only good way around this is to document the perl5i command line utility inside the module.
This makes sense in that there is some duplication in the docs in both describing wtf perl5i does. Also makes sure people looking for docs for the module see the script is there too.
Okay, I'll add some docs to the module documentation.