Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

The Monastery Gates

( #131=superdoc: print w/replies, xml ) Need Help??

Donations gladly accepted

  • (Sep 10, 2018 at 22:53 UTC) Welcome new users!
If you're new here please read PerlMonks FAQ
and Create a new user.

New Questions
How does rename() work on read-only files?
3 direct replies — Read more / Contribute
by j41r
on Dec 10, 2018 at 19:56

    Dear monks,

    I'm one of the weird people that hates to ask questions but instead loves to RTFM. This time I'm really stuck with this subject that I'm pretty sure is trivial for all of you but, for me, it's so important that I didn't hesitate to raise my hand to ask about it, so here you go:

    I was reading about Why does Perl let me delete read only files? Why does i clobber protected files? Isn't this a bug in Perl?, and while the executive summary was pretty much understandable, that wasn't enough for me and I went the extra mile by reading the elaborately and painstakingly explanation available in the file file-dir-perms

    That's an amazing explanation, however how rename() actually works on read-only files just went over my head. Could anyone please help me out understand these two cases?

    1. When running perl -i.bak -pe 1 alpha/foo, foo's inode is preserved and foo.bak gets a new inode.
    2. When running perl -i.bak -pe 1 alpha/bar, bar gets a new inode and bar.bak gets the previous bar's inode.

    I also read How can I reliably rename a file?, which says (emphasis mine):

    It may be more portable to use the File::Copy module instead. You just copy to the new file to the new name (checking return values), then delete the old one. This isn't really the same semantically as a rename(), which preserves meta-information like permissions, timestamps, inode info, etc.

    but it seams to just add insult to injury, so any help would be appreciated.

multiple hash compare, find, create
8 direct replies — Read more / Contribute
by Anonymous Monk
on Dec 10, 2018 at 12:12

    Hello Perl Monks. First time post, long time gleaner of information which is and has been very appreciated. Anyway I have an issue that I truly need some assistance with. I am fairly new to hash tables. What I need to do is compare three hash tables each containing between 14 million and 28 million keys with associated values. Sure, I could nest some loops and let it rip and come back in a year or so to see if it worked and hoping that no server crashes occurred.

    Optimally, I'd like to find the common keys between each of the three hash tables and gather the values from each of the three hash tables and create a new, forth hash table that contains  key => [value_hash_1, value_hash_2, value_hash_3] And for a key that does not exist in all three hashes, do nothing; the resulting forth hash table will have somewhat less than 14 million k/v pairs.

    Do I make sense? And the solution is most likely posted, but I had difficulty finding it.

    Thank you very much for your assistance!

File::Temp survival and scope created by "do"
1 direct reply — Read more / Contribute
by vr
on Dec 10, 2018 at 05:40

    In Spreadsheet::Read Win32::LongPath::openL, I wrote something like:

    my $tmp = File::Temp-> new( SUFFIX => '.ods' )-> filename; copyL 'whatever.ods', $tmp; say 'ok' if defined ReadData( $tmp );

    which I later realized didn't work exactly as intended. Temp file (and object) no longer existed after 1st statement, copyL simply "hijacked" file name, and temp file wasn't cleaned-up at program end.

    Initially I wanted it shorter as

    copyL 'whatever.ods', my $tmp = File::Temp-> new( SUFFIX => '.ods' )-> + filename; say 'ok' if defined ReadData( $tmp );

    it wasn't "ok" for reason stated above. Instead, in retrospect, this would work:

    copyL 'whatever.ods', my $tmp = File::Temp-> new( SUFFIX => '.ods' ); say 'ok' if defined ReadData( $tmp-> filename );

    Then object stringifies itself in 1st statement, and survives because bound to a variable. From practical point, that's about it all. However, during investigation I was puzzled by unexpected (though maybe not practically useful) behaviour:

    use 5.014; use warnings; package Temp; use parent 'File::Temp'; sub new { my $self = shift; $self-> SUPER::new( DIR => '.' ) } sub DESTROY { my $self = shift; say 'global' if ${^GLOBAL_PHASE} eq 'DESTRUCT'; $self-> SUPER::DESTROY } package main; use File::Copy; sub foo { my $h = Temp-> new } die unless -f 'x'; # this file must exist copy 'x', my $fn1 = Temp-> new-> filename or die; copy 'x', my $fn2 = do { Temp-> new }-> filename or die; copy 'x', my $fn3 = do { my $h = Temp-> new }-> filename or die; copy 'x', my $fn4 = foo-> filename or die; say 1 if -f $fn1; say 2 if -f $fn2; say 3 if -f $fn3; say 4 if -f $fn4;

    which says "3". All copying completes successfully, and I'd expect objects destroyed and temp files deleted by end of each of 4 statements. But, somehow, object survives if bound to lexical variable in "do" block, but not in case of subroutine call. Why?

    Auxiliary question: object was not destroyed during global destruction at program end, but when?

Example of building/deploying perl program like StrawberryPerl
3 direct replies — Read more / Contribute
by xiaoyafeng
on Dec 10, 2018 at 03:04

    Hi, Monks

    Recently,I have to port my program from Windows to Linux since the whole industry I've been worked on has gradually switch to it. Let me mention a little bit of current situation: When I'm on windows, I maintain an environment of Perl which is based on portable strawberry Perl. I added some more Perl libraries to Perl sub directory, some c libraries to c directory, and some executables to bin then I test my program on this . When the first installation, I installed the whole perl dist on customer machines, and with the every updates, I just need to change several files or scripts accordingly. Being about 8 years, this way works fine.

    It doesn't work on Linux world. Since the every Linux dist has already maintain a perl respectly which I may not test So I want to isolate my perl environment from system perl including 3rd binary libraries like I did on windows. but How install them(perl and c libraries) on individual users and the program can find it? I'm heard that the Docker would be suitable for this scenario, but I'm not sure. maybe it's out of topic, but if any monks know that Please point it out also.

    Based on Perl, as my poor perl knowledge (Little linux), there are several weapons I could use: perlbrew, Alien and Task family. As I preliminary think, I could use perlbrew to build a base perl dist, set it to default on .profile file. then use/create Alien module to add binary libraries for perl or directly using and Task for installing perl library. At last tar the whole directory and sent to customer! Am I right? Please enlighten me before I dive in, or point me out a better way! Thanks in advance.

    Andy




    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Spreadsheet::Read Win32::LongPath::openL
2 direct replies — Read more / Contribute
by Anonymous Monk
on Dec 09, 2018 at 08:48

    Hi

    I am trying to open Excel and ODS files with longnames paths (and possibly not Latin characters) on Windows. I use Win32::LongPath::openL to open the files. For XLS I then use Spreadsheet::ParseExcel. This works fine. For ODS I use Spreadsheet::Read. This doesn't work.

    use Spreadsheet::Read; use Spreadsheet::ParseExcel; my $InputFile; Win32::LongPath::openL (\$InputFileReadable, '<', $InputFile); #opening XLS my $parser = Spreadsheet::ParseExcel->new(); my $workbook = $parser->parse($InputFileReadable); if ( defined $workbook ) { print "I could read the XLS file\n"; } #opening ODS my $workbook2 = ReadData ($InputFileReadable); if ( defined $workbook2 ) { print "I could read the ODS file\n"; }

    Why is $workbook2 always undefined?

Browser::Open Windows metacharacters
2 direct replies — Read more / Contribute
by IB2017
on Dec 09, 2018 at 05:08

    Hello Monks,

    is it a bug in Browser::Open or a 'bug' in my module understanding? The following doesn't work on Windows 10:

    my $url='https://www.google.com/search?q=finance&source=lnms&tbm=isch' +; my $ok = open_browser($url);

    It breaks after shell metacharacters (in this case &) which Windows is trying to use as commands. Should I pass $url in a different way?

How Can My Perl/Tk Program use a Defined Font for All Widgets?
4 direct replies — Read more / Contribute
by ozboomer
on Dec 08, 2018 at 23:21

    Something of a silly question, I fear...

    The code:

    use strict; use warnings; use Tk; my $tstate = 0; # State of the dynamic text my $mw = MainWindow->new( # Create a window -width => 300, -height => 110, ); $mw->minsize( 300, 110 ); $mw->fontCreate('standard_font', # ..and some fonts +for it -family => 'Arial', -size => 12, -weight => 'normal'); $mw->fontCreate('alternate_font', -family => 'Times', -size => 24, -weight => 'bold'); $mw->fontCreate('my_default_font', -family => 'Sans', -size => 8, -weight => 'normal'); # $mw->configure(-font => 'my_default_font'); # '-font' is unkn +own to configure() # $mw->fontConfigure('my_default_font'); # Does nothing my $static_text_lbl = $mw->Label( # Uses the system ' +default' font -text => 'UNCHANGING TEXT', )->pack(-anchor => "center", -side => 'top'); my $text_lbl = $mw->Label( # An object with an + assigned font -text => 'DYNAMIC TEXT', -font => 'standard_font', )->pack(-anchor => "n", -side => 'top'); my $Exit_Btn = $mw->Button( # A button to exit -text => 'Exit', -width => 8, -command => sub { $mw->destroy }, )->pack(-anchor => 's', -side => 'bottom'); my $Toggle_Btn = $mw->Button( # ..and another to +toggle the font -text => 'Toggle', -command => [ \&fix_fonts ], )->pack(-anchor => 's', -side => 'bottom'); MainLoop; # ---------- sub fix_fonts { if ($tstate ^= 1) { $text_lbl->configure(-font => 'alternate_font') } else { $text_lbl->configure(-font => 'standard_font') } } # [eof]

    I can assign a different font from the standard 'system defined' type through the command line invocation, viz:-

          c:\> perl prg.pl -font "sans 12"
    

    ...and the window and its child widgets will all have the "sans 12" font (unless it's explicitly changed).

    However, it appears that if I want to do that same thing within the program itself, I have to do it explicitly on every widget, which seems redundant and annoying.

    Is there a defined/accepted/working way to do things 'globally' within the program?

    I've tried a couple of ways to apply a font to the Main Window (see in the code) and they don't seem to work.

    I've tried checking on-line, in the Monastery, the O'Reilly books and some various examples of code... and I can't find anything that will do what the command line approach does.

    This example is using ActiveState Perl v5.20.2 under Windows 8 32-bit.

    I'd greatly appreciate any clues.

    Thanks.

code duplicate in tests -- code or custom module only needed to test
4 direct replies — Read more / Contribute
by Discipulus
on Dec 06, 2018 at 05:42
    Hello folks!

    I'm writing a lot of test nowadays (finally!) and currently I have a lot of duplicated code in them. This is because I'm testing a simple backup solution and many tests of mines requires backup scenarios to be present in a temporary folder.

    So I create and delete files and folders in my tests, I read a write files permissions etc.. and to accomplish these tasks I use CPAN modules not needed by my module but only during tests.

    1) I can have a dedicated module with all required modules imported an exposing all subs I need. Where? How? Where the dependencies of this (somehow private module) have to be specified? In the BUILD_REQUIRES in the Makefile.PL of the main module?

    2) have a special part of the main module (or a dedicated package?) loaded only during tests? How to trigger this behaviour?

    3) (probably worst approach) build only one test file, a big one with all modules used and all subs defined in the very same file

    I did not found anything related to the matter (maybe because of generic terms of the search..) nor advice in my bibliotheca and asking in the chatter box I had a precious suggestion by Corion that i'll present below (for future readers) but I also want to know from you other possible approaches or tecniques, and if i missed some detail:

    Corion suggested option 1: and pointed me to his WWW-Mechanize-Chrome's helper.pm testing module. The solution is simple and worth to share (I see # hide from CPAN indexer can some elaborate this?).

    Have you other approach? Some quirk I missed? Something to pay attention to?

    thanks



    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Multiuser app with SQLite, Dancer2 and CLI
5 direct replies — Read more / Contribute
by kaldor
on Dec 04, 2018 at 16:02

    Hello, this is my first question...

    I'd like to write a small multi-user text application accessible by different interfaces (web, terminal, ssh and maybe others). The typical scenario is a few hundreds total users, with a dozen users connected at the same time.

    I have the following prototype working : SQLite + DBI + Dancer2 web app running as FastCGI (on mac/linux). Now I wonder how to add CLI interfaces without duplicating code and logic... As fas as I understand, the SQLite "file" can be accessed safely by different processes.

    Should I just write a basic CLI that accesses the DB directly and use xinetd? Or do I have to write a backend that accesses the DB and executes the logic for UI-only clients?

    Suggestions and advice are welcome. Thank you.

New Meditations
Camel vs. Gopher
3 direct replies — Read more / Contribute
by reisinge
on Dec 08, 2018 at 14:16

    I've been using Perl for several years mostly for small to medium sized programs of sysadmim type (automation, gluing, data transformation, log searching). Recently I started to learn Go. I wanted to write something in both languages and compare. Here goes.

    The Perl code is more than 2 times smaller:

    $ ls -l x.* | perl -lanE 'say "$F[8]\t$F[4] bytes"' x.go 694 bytes x.pl 294 bytes

    Perl code is more than 4 times slower when run ...

    $ time go run x.go > /dev/null real 0m1.222s user 0m1.097s sys 0m0.220s $ time perl x.pl > /dev/null real 0m5.358s user 0m4.778s sys 0m0.497s

    ... and more than 5 times slower when I built the Go code:

    $ go build x.go $ time ./x > /dev/null real 0m0.947s user 0m0.890s sys 0m0.126s

    The code generates 10 million random integers from 0 to 9. Than it counts the occurrence of each generated integer and prints it.

    $ cat x.go package main import ( "fmt" "math/rand" "time" ) func main() { // Seed the random number generator seed := rand.NewSource(time.Now().UnixNano()) r1 := rand.New(seed) // Generate random integers var ints []int for i := 0; i < 10000000; i++ { n := r1.Intn(10) ints = append(ints, n) } // Count ints occurrence count := make(map[int]int) for _, n := range ints { count[n]++ } // Sort ints var intsSorted []int for n := range count { intsSorted = append(intsSorted, n) } // Print out ints occurrence for n := range intsSorted { fmt.Printf("%d\t%d\n", n, count[n]) } } $ cat x.pl #!/usr/bin/perl use warnings; use strict; # Generate random integers my @ints; push @ints, int rand 10 for 1 .. 10_000_000; # Count ints occurrence my %count; $count{$_}++ for @ints; # Print out ints occurrence for my $int ( sort keys %count ) { printf "%d\t%d\n", $int, $count{$int}; }

    In conclusion I must say that I like both languages. I like beer too :-).

    Always rewrite your code from scratch, prefefably twice. -- Tom Christiansen
Delegating responsibility of one's CPAN distributions
4 direct replies — Read more / Contribute
by stevieb
on Dec 04, 2018 at 20:21

    Say, for example, I get eaten by a bear, roll my truck off into the lake, get crushed by falling mountain boulders or otherwise burn in a fire, I'm wondering what will happen with my CPAN distributions.

    I mean, I won't care if I'm dead, but if they are being used (from what I can tell, they are in a 'minimalistic' sense (I don't know numbers)), what happens? By default after years of trying to understand, they'll fall into a state of disrepair and then go through the normal channel of adaption.

    I'm wondering what my fellow Monks think about this.

    My question here, is would it be worth working it up the chain to have a "will" of sorts; someone you could "dedicate" your distributions to, within the Makefile (or whatever dist thingy one uses). A new attribute, effective across all build platforms and accepted by CPAN, that acknowledges who you want to oversee what you've written.

    I'm not talking about co-auth here. I'm talking about someone who may not even care about one's work. I'm talking about someone who cares about Perl enough that one would feel comfortable with rightfully distributing one's distributions accordingly, because they are somewhat familiar with the Perl ecosystem.

    This is totally off the wall, but I've been through so much in the last 24 months, that I'm trying to think of everything.

    Would a IF_I_DIE flag within a Makefile.PL that is easily searchable be a good idea, or an idea of a madman who keeps buying sensors to write Perl around?

New Obfuscated Code
VT100 Screensaver
1 direct reply — Read more / Contribute
by kschwab
on Dec 09, 2018 at 16:27

    Only works on Unix like machines...requires a VT100 compatible terminal like an xterm, and a working "stty" binary. Handles resizing the window while it's running. Ctrl-C to stop it.

    #!/usr/bin/perl use warnings;use strict;my($r,$c);$|=1;init(); sub init{print "\ec";($r,$c)=split' ',qx"stty size";$r-=5;$c-=16}; $SIG{INT}= sub{print "\ec\n";exit};$SIG{WINCH}=sub{init()}; $_='!X!E!EIC%IC%IC%!X!ECu#kCD@3ilowg!E!WICD@biloQgIO#kAr@DiloT@/@j'. '@D@j@%IO#myD@gg!QCu#kC%IO#kO#gO#gC%!MIC%!QCu#kC%IO#ne#me#ni%!MICD'. '@f@/iloQK';s/!/4pa/g;s/@/ilp/g;s/#/KW/g;s/%/Ag/g;tr|A-Za-z0-9+/| -_|; @_=split(/\n/,unpack('u',join($',map(chr(32+length($_)*3/4). $_,/(.{1,60})/gs))));print "\ec\e[2J\e[?25l";srand(); for (;;) { my($x,$y)= map{int(rand($_))+1}($c,$r); for(0..4){print "\e[".($y+$_).";${x}H".$_[$_];} select($\,$\,$\,rand(1.2)+.3); for(0..4){print "\e[".($y+$_).";${x}H"." "x16;} }
Christmas Package Obfuscation
1 direct reply — Read more / Contribute
by kschwab
on Dec 08, 2018 at 14:11
    #!/usr/bin/perl $;;$^;s#^#$\ _-~,..___ .-' .--._ ```--.-----.___ ._^---- (`-...`-. _/,----. ) ````---=. _.-'' ````-- `.___.-.) (---=='' .-' | _.-' _.-. )(`.-._``--.._ .' | |`---..__ .-'.-'.' )| |_ ``--...`. | | ``--.._ ,'.-' ( ( `-.`-. .'| : | | | | --.._`. ) `. `. | : | | | | ( )-.._.') ) ) : | | | | | | | ( ( ) : | | | | (_( | ) ) | : .' | | | | L/ | : .' (__ | | | | :.' `-.._ | | | | : `-.._ | | | |/ `--`_|_ | .' `._ | .' ``-.__ | .' `--`; # and "Happy Holidays" or Merry Christmas! print "Is print broken?\n";print;# guess not?
Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2018-12-11 12:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How many stories does it take before you've heard them all?







    Results (54 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!