Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

The Monastery Gates

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

Donations gladly accepted

If you're new here please read PerlMonks FAQ
and Create a new user.

New Questions
Accent file names issue
1 direct reply — Read more / Contribute
by ruimelo73
on Sep 20, 2017 at 06:41

    I'm portuguese and like so many people that live in countries with latin languages (portuguese, spanish, french, italian, etc) I have to deal with accent file names. Other non-latin languages have the same problem for sure (german, dutch, etc). The context here is Windows using NTFS drives, using Unicode to set up the files names. I'm using the latest perl version, that supports Unicode.

    For example, I have a directory/folder in "c:\users\someuser\documents" named "documentação" ("documentation" in english). The full path will be "c:\users\someuser\documents\documentação". Now, if I do this:

    use strict; our $dp; $dp = "c:\\Users\\someuser\\Documents\\documentação"; if (-d $dp) { print "ok\n"; } else { print "nope\n"; }

    It will return "nope"...
    If I change the text to "documenta\x{00E7}\x{00E3}o", it returns "ok"...
    Printing the string variable will show the same thing...
    If I use opendir/readdir in the "c:\users\someuser\documents" directory it will read "documentação" perfectly and -d will work fine...
    The -d simply does not work with the direct text on the string variable...
    If I add code to set the variable using command line argument in a dos console it will return "ok" also.

    I wasted hours reading unicode and perl documentation, and trying diferent methods (utf8, encoding, deconding, locale, etc) for correcting this, but nothing works. It is a problem with the way perl codifies the string internaly. I suppose that using some sort of perl command line option would do some thing that could solve the issue but this is not the way to resolve this.

    In the end, I copy the string from itself, "character" by "character", and it worked:

    use strict; our $dp; $dp = "c:\\Users\\someuser\\Documents\\documentação"; $dp = &clean_copy($dp); if (-d $dp) { print "ok\n"; } else { print "nope\n"; } sub clean_copy { my $old_str = shift; my $new_str = ""; foreach my $i (0..(length($old_str-1))) { my $c = substr($old_str, $i, 1); $new_str .= $c; } return($new_str); }

    This is a bit ridiculous but it works... Somehow the "char-by-char" copying "cleans" some perl internal encoding related to unicode stuff.

    Unicode is a wonderful thing but reading about the evolution of Unicode you start thinking that Unicode is now on the same level of confusion to what happened to the ancient codepages... I hope that some one teachs me a lesson, or this sort of weirdness can be solved in future versions of perl.

    Thank you / Obrigado.

Perl -T vs Mime::Types
2 direct replies — Read more / Contribute
by roperl
on Sep 19, 2017 at 15:03
    What method is better to test if file is a plain ascii text file. I'm already checking MIME types of non-text file with File::Type.
    Should I check the text files with perl's -T like so:
    if(-T $file) { print "$file is an ascii text file \n"; } else { print "Not an ascii text file \n"; }
    Or check that it matches application/octet-stream MIME type like so:
    my $ft = File::Type->new(); my $type = $ft->mime_type($file); if ( $type eq "application/octet-stream" ) { do this.. } else { do that.. }
[emacs] dual files mangling Perl and Lisp code?
4 direct replies — Read more / Contribute
by LanX
on Sep 19, 2017 at 04:15

    is there a recommended way to mix Perl and eLisp code in one file without caring about escaping, such that it can be executed in both ways?

    Something like

    my $perl; #code ... __DATA__ (ELisp...)

    Just that emacs ignores the Perl part when executing the file?

    There are similar examples with bash and bat...


    Just realising that ; is a comment symbol in lisp and a no op in Perl, this might be simplistic way to do it. ..

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Inline::C in a Perl module
2 direct replies — Read more / Contribute
by enemyofthestate
on Sep 18, 2017 at 14:33

    I am trying to use Inline::C in a perl module. The C code appears to compile fine (at least there is a .so file in the right place) but the module does not return a true value to the calling program and I cannot figure out how to make that work. I've tried putting the usual "1;" at various places in the code but it either chokes when compiling or tells me:

    " did not return a true value at bin/dldtest.fcgi line 11."

    Anyone know how to make this work?

    This is some stripped down code I am using to test with:


    #!/usr/bin/perl use strict; use warnings; use File::Basename; use FindBin; use lib dirname($FindBin::Bin) . "/modules"; use DLDtest; my ($dlid,@dlfiles) = dld_initialize("lic_file", "123456", 5, "/path/t +o/data/files"); exit 0;

    package DLDtest; use strict; use warnings; use Exporter qw(import); use English; our @EXPORT = qw (dld_initialize); #------------------------------------------------ # initialize dld and open data files #------------------------------------------------ sub dld_initialize { my ($lic_file, $password, $num_files, $dl_format) = @_; my @files = (); # initalize the DLD library my $dlid = dl_DlInit(""); # set the license file and password unless (dl_DlSetLicense($dlid, $lic_file, $password)) { return (0,@files); } # open the DLD files for (my $cntr = 0; $cntr < $num_files; $cntr++) { my $path = sprintf($dl_format, $cntr + 1); my $fileid = dl_DlFileOpen($dlid, $path); $files[$cntr] = $fileid ? $fileid : 0; } return ($dlid,@files); } #------------------------------------------------ # C functions to interface with Pitney library #------------------------------------------------ use Inline (C => Config => DIRECTORY => '/var/www/addrez/Inline', INC => "-I/var/www/addrez/ext.att/include", LIBS => '-L/var/www/addrez/ext.att/lib -ldemolibMT'); use Inline "C"; Inline->init; __DATA__ __C__ #include "dl.h" /*----------------------------------------------- * Initialize the DLD librariy *---------------------------------------------*/ long dl_DlInit (SV* initPath) { return DlInit(SvPV (initPath, PL_na)); } /*----------------------------------------------- * associate a license file and password with dl *---------------------------------------------*/ int dl_DlSetLicense(long dl, char* licenseFile, long password) { return DlSetLicense(dl, licenseFile, password); } /*----------------------------------------------- * open a data file and return FileID *---------------------------------------------*/ long dl_DlFileOpen (long dl, char *path) { return DlFileOpen(dl, path); }
(Solved) Extracting sometimes null string from text variable
2 direct replies — Read more / Contribute
by Marshall
on Sep 17, 2017 at 14:24
    I am parsing a $text variable from which I want to extract a Club name.
    I have a solution that "works" as shown below.
    I have been unable to do this in a single regex which handles both of my cases. So I just used 3 statements. This is a pragmatic "do what works" situation and is fine as far as that goes. However, in the search for elegance, I suspect that a single regex could be constructed that handles both cases?

    In case2, there is a new line right after Club:. My attempts at a single regex often wind up capturing Comments: instead of a null string for Club name. Ideas welcome.

    #!/usr/bin/perl use strict; use warnings; my $case1 = "Club: Some Club Comments: "; my $case2 = "Club: Comments: "; foreach my $text ($case1, $case2) { # extract Club name (my $club) = $text =~ /Club:(.*)/; # need to allow for blank Club + name $club =~ s/^\s*//; $club =~ s/\s*$//; print "line before name\n"; # print out to make sure $club doesn' +t have a \n print "extracted Club name: '$club'\n"; print "line after name\n"; } __END__ line before name extracted Club name: 'Some Club' line after name line before name extracted Club name: '' line after name ======== I've tried things like: /Club:\s*(.*)[ ]*\n/ and various other encantations, but that picks up 'Comments:' intead of a blank Club name line before name extracted Club name: 'Some Club' line after name line before name extracted Club name: 'Comments:' line after name
    LanX and Anonymous Monk came up with the ball!
    I hadn't seen \h before, but it works here!
    #!/usr/bin/perl use strict; use warnings; my $case1 = "Club: Some Club Comments: "; my $case2 = "Club: Comments: "; foreach my $text ($case1, $case2) { # extract Club name (my $club) = $text =~ /Club:\h*(.*?)\h*\n/; # need to allow for b +lank Club name print "line before name\n"; # print out to make sure $club doesn' +t have a \n print "extracted Club name: '$club'\n"; print "line after name\n"; } __END__ line before name extracted Club name: 'Some Club' line after name line before name extracted Club name: '' line after name
tkpp fails at very end
3 direct replies — Read more / Contribute
by smh
on Sep 17, 2017 at 01:07

    I am running tkpp to convert my perl script to an "exe" file. my environment is ASP perl 64 bit V5.24 and I have installed "PAR-Packer-1.037". The script I am trying to convert, had no issues when I was using ASP PDK v9.2. Now every thing seems to work find except the end with the following error message at the veru last line in the log file.

    C:\Perl64\site\bin\pp.bat: Failed to extract a parl from 'PAR::Strippe +dPARL::Static' to file 'C:\Users\Shahriar\AppData\Local\Temp\parlGiqe +nzz.exe'Building Q:\W_PERL\_000_Dev\Netlister\Netlister.exe failed : The system cannot find the file specified.
Regex get Text between two strings with colon
3 direct replies — Read more / Contribute
by MurciaNew
on Sep 16, 2017 at 13:49
    Hi Monks,

    i have a regex problem. I want to get the text between two words with colon (like Example: or Epikrise:)

    I have files (newLine is "\r\n").

    Example of just two files: <<< start file 1>>> Test:\r\n blablabla1\r\n blablablabla2\r\n blablablablabla3\r\n blablablab4\r\n blablablaba5\r\n Test1:\r\n lalala1\r\n lalala2\r\n Hello3:\r\n mymymymy\r\n <<< end file 1>>> <<< start file 2>>> Test:\r\n blablabla1\r\n blablablabla2\r\n blablablablabla3\r\n blablablab4\r\n blablablaba5\r\n blablablaba6\r\n Test3:\r\n lalala1\r\n lalala2\r\n lalala3\r\n City:\r\n Gigi\r\n lulu\r\n Kuku\r\n <<< end file 2>>>

    With a regexp I want to get all text between "Test:" to that next line with a string with ":"(colon) (for the examples "Test2:" for file 1 or "Test3:" for file 2

    as result Test="blablabla1\r\n blablablabla2\r\n blablablablabla3\r\n blablablab4\r\n blablablaba5\r\n"

    or Test="blablabla1\r\n blablablabla2\r\n blablablablabla3\r\n blablablab4\r\n blablablaba5\r\n blablablaba6\r\n" )

    I tried (.+?(\r\n.+){1,}?(?!\w+?:)) but it does not work

    Please help me..... Thanks

    MurciaNew (Guido)

Drawing a Tile using SDLx::Sprite
No replies — Read more | Post response
by Muskovitz
on Sep 16, 2017 at 12:54
    Hello monks!

    i am trying to draw a 2d-tiled map in SDL Perl using the SDLx::Sprite module but i was wondering is this really the proper way to draw a tiled map in SDL Perl? Or there are other ways to do it?
    Here is how i draw a tile in Perl SDL

    my @tile2=map{ my $sprite = SDLx::Sprite->new( image => 'img/tile/tile2.png', # or surface => SDL::Surfac +e x=>int rand(500)-20, y=>400 ); } 1 .. 50; # .... etc ..... for(@tile2){ $_->draw_xy($app,$_->x,$_->y); }

    Perl Monks please guide me.

problem with Crypt::PBKDF2
1 direct reply — Read more / Contribute
by jamroll
on Sep 15, 2017 at 22:44
    okay. so i have a script, "" which spits out this error:

    Use of uninitialized value in subroutine entry at /usr/local/share/perl/5.24.1/Crypt/PBKDF2/Hash/ line 19.

    i've done some "debugging" and have found the error happens on this line of "": $account{password} = $pb->generate($account{passwordagain});

    I even tried to change it to:

    my $temp = $pb->generate($account{password}); no dice!

    yet, my "" script doesn't issue the error and the code is pretty much exactly the same stuff:

    my $newdbpw = $pb->generate($newpw); i need to post ALL of the code, or is this enough to get us started?

    some system stats? ubuntu 17.04 and perl5.24.1

    Sincerely, Jarett

MySQL DB Connection
4 direct replies — Read more / Contribute
by clm314159
on Sep 15, 2017 at 11:13

    Hi, I'm trying to show someone how to connect to a MySQL DB with Perl. I've done this before but it was about 10 years ago. I know it is a pretty straight forward process except it is full of little details that must all be addressed. So my question is, Does anyone know of a good up to date tutorial for doing this on Windows? The ones I've been finding are either not for MySQL and there is the problem of interpreting the info from one DB to MySQL (currently I'm working from an oracle tutorial trying to install the driver, the oracle driver is clearly labelled as such but I cannot find a MySQL driver that is clearly labelled in the ppm) or the tutorial is 15 years out of date.

    Any info you could point me at would be appreciated,
Win32::API and keyboard hook
1 direct reply — Read more / Contribute
by frazap
on Sep 15, 2017 at 05:19

    I have working code in Java Jini and C++ that creates a keyboard hook. Basically, the programm listen to the key pressed and react when some selected keys are used.

    I would like to implement the same with perl. I tried to use Win32::API.

    The script below is a try but it hangs in the MsgLoop sub: If $msg is Win32::API::Struct object, the call $GetMsg->Call($msg, undef, 0,0) does not return and produces a bunch of warnings Use of uninitialized value in pack in Win32/API/

    I have tried to parse the MSG struct code using Convert::Binary::C, but I'm not sure what to do next. My code is mixt with using Convert::Binary::C->pack with an empty Win32::API::Struct. Passing the result of this to the imported GetMessage function gives Win32::API::Call: parameter 1 must be a Win32::API::Struct object!

    Thanks for any advice.

    use strict; use warnings; use Data::Dumper; use Win32::API; use Win32::API::Callback; use Convert::Binary::C; #use experimental 'bitwise'; =for comment +neventhook_help/ +.85).aspx +.85).aspx +.85).aspx =cut BEGIN { $Win32::API::DEBUG = 1; } my $WH_KEYBOARD_LL = 13; Win32::API::Struct->typedef( POINT => qw( LONG x; LONG y; ) ); use constant { KEYEVENTF_EXTENDEDKEY => 0x0001, KEYEVENTF_KEYUP => 0x0002, KEYEVENTF_SCANCODE => 0x0008, KEYEVENTF_UNICODE => 0x0004, INPUT_KEYBOARD => 1 }; Win32::API::Struct->typedef( MSG => qw( HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; ) ); Win32::API::Struct->typedef( KEYBDINPUT => qw( WORD wVk; WORD wScan; DWORD dwFlags; DWORD time; UINT_PTR dwExtraInfo; DWORD junk1; DWORD junk2; ) ); Win32::API::Struct->typedef( INPUT => qw( DWORD type; KEYBDINPUT ki; ) ); my $code = <<CCODE; typedef unsigned long DWORD; typedef unsigned short WORD; typedef unsigned int UINT_PTR; struct INPUT { DWORD type; struct { WORD wVk; WORD wScan; DWORD dwFlags; DWORD time; UINT_PTR dwExtraInfo; DWORD junk1; DWORD junk2; } ki; } ; typedef void *PVOID; typedef PVOID HWND; typedef unsigned int UINT; typedef unsigned int UINT_PTR; typedef UINT_PTR WPARAM; typedef long LONG_PTR; typedef LONG_PTR LPARAM; struct MSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; struct { long x; long y; } pt; }; CCODE my $cparser = Convert::Binary::C->new->parse($code); my $GetCurrentThreadId = new Win32::API( 'kernel32', 'GetCurrentThreadId', '', 'N' ); print Win32::GetLastError(), "\n"; #0 # my $SetWindowsHookEx = new Win32::API('user32', 'SetWindowsHookEx', + 'NKPP', 'P'); # my $SetWindowsHookEx = Win32::API->Import('user32', 'HHOOK SetWindo +wsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, int dwThreadId)') +; # #my $CallNextHookEx = Win32::API->Import('user32', 'CallNextHookEx +', 'PNNN', 'N'); #my $GetMsg = Win32::API->Import('user32', 'GetMessage', 'NNII', 'i' ) +; my $SetWindowsHookEx = Win32::API->Import( 'user32', 'SetWindowsHookEx', 'IKNI', 'N' ) ; #, "idHook, HOOKPROC lpfn, HINSTANCE hMod, int dwThreadId"); die( "Failed to import" . $^E ) if !$SetWindowsHookEx; my $CallNextHookEx = Win32::API->Import( 'user32', 'LRESULT WINAPI CallNextHookEx(HHOOK hhk, int nCode, WPARAM wPara +m, LPARAM lParam)' ); my $GetMsg = Win32::API->Import( 'user32', 'BOOL WINAPI GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin +, UINT wMsgFilterMax)' ); die "Error: $^E" if !$GetMsg; my $TranslateMsg = Win32::API->Import( 'user32', 'TranslateMessage', 'N', 'i' ); die "Error: $^E" if !$TranslateMsg; my $DispatchMsg = Win32::API->Import( 'user32', 'DispatchMessage', 'N' +, 'N' ); die "Error: $^E" if !$DispatchMsg; my $GetModuleHandle = Win32::API->Import( 'kernel32', 'HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName)' ); my $UnhookWindowsHookEx = Win32::API->Import( 'user32', 'BOOL WINAPI UnhookWindowsHookEx(HHOOK hhk)' ); my $SendInput = Win32::API->Import( 'user32', 'UINT WINAPI SendInput(UINT nInputs, LPINPUT pInputs, int cbSize)' + ); die "Error: $^E" if !$SendInput; print Win32::GetLastError(), "\n"; #127 sub MsgLoop { my $msg = Win32::API::Struct->new("MSG"); print "msgloop\n"; my $lp = $cparser->pack( "MSG", $msg ); # print "getmsg:" , Dumper ($GetMsg->Call($msg, undef, 0,0)); # die; my $res; while ( $res = $GetMsg->Call( $lp, undef, 0, 0 ) ) { die "Error in GetMsf" if ( $res == -1 ); # while (GetMsg($msg, undef, 0,0)) { die unless $msg; $TranslateMsg->Call($lp); $DispatchMsg->Call($lp); } } sub KeyboardHook { my ( $nCode, $wParam, $lParam ) = @_; print "kbhook\n"; print join( ", ", @_ ) . "\n"; #print "nCode=$nCode, wParam=$wParam, lParam=$lParam\n"; $CallNextHookEx->Call( 0, $nCode, $wParam, $lParam ); } sub registerHook { my $ThreadId = $GetCurrentThreadId->Call(); print "ThreadID : $ThreadId\n"; my $hMod = $GetModuleHandle->Call(undef); my $KeyboardHookCallback = Win32::API::Callback->new( \&KeyboardHook, "NNNN", "V" ); my $Hook = $SetWindowsHookEx->Call( $WH_KEYBOARD_LL, $KeyboardHookCallbac +k, $hMod, $ThreadId ); MsgLoop(); $UnhookWindowsHookEx->Call($Hook); return $Hook; } sub unregisterHook { $UnhookWindowsHookEx->Call(shift); } sub sendString { my $val = shift; my @val = split( //, $val ); my $input_str = Win32::API::Struct->new("INPUT"); my @input = ( $input_str, $input_str ); $input[0]->{type} = INPUT_KEYBOARD; $input[0]->{ki}->{dwFlags} = KEYEVENTF_UNICODE; $input[1] = $input[0]; $input[1]->{ki}->{dwFlags} |= KEYEVENTF_KEYUP; for my $v (@val) { ( $input[0]->{ki}->{wVk}, $input[1]->{ki}->{wVk} ) = ( 0, 0 ); ( $input[0]->{ki}->{wScan}, $input[1]->{ki}->{wScan} ) = ( $v, + $v ); for my $i ( 0 .. 1 ) { my $lp = $cparser->pack( "INPUT", $input[$i] ); $SendInput->Call( 1, $lp, $cparser->('INPUT')->sizeof ); #print 'Error: ', Win32::FormatMessage( Win32::GetLastError() ) unless + ( $SendInput->Call( 2, \@input, 2 * $input_str->sizeof ) ); } } } my $hook = registerHook(); print "hook:", Dumper($hook), "\n"; sendString("abc"); unregisterHook($hook);
Log4Perl: file permissions
2 direct replies — Read more / Contribute
on Sep 15, 2017 at 03:34
    Hi, I try to set permissions for logfiles generated by Log4Perl ... The logger is initialized by a configfile
    In the file I have this configuration:
    log4perl.appender.MasterLog = PCIDSSAppender log4perl.appender.MasterLog.filename = /var/log/application/perl.log log4perl.appender.MasterLog.mode = append log4perl.appender.MasterLog.size = 10000000 log4perl.appender.MasterLog.max = 25 log4perl.appender.MasterLog.permissions = log4perl.appender.MasterLog.layout = PatternLayout log4perl.appender.MasterLog.layout.ConversionPattern=%d %H [%P:%p] %F: +%L:- %m%n
    This leads to this permissions: -rw-r--r-- What I need is 600: -rw------- How to configure this ?? A setting off 600 leads to this: ---x-wx--T I'm really confused about this ...
New Meditations
[RFC] File::Replace
No replies — Read more | Post response
by haukex
on Sep 20, 2017 at 05:50

    Many of you are probably aware of the pattern of opening a temporary file, reading from the original file and writing the modified contents to the temporary file, and then renameing the temporary file over the original file, which is often an atomic operation (depending on OS & FS). I recently wrote a module to encapsulate this behavior, and here is one of three interfaces that are available in File::Replace. There are several options to configure the behavior, including the ability to specify PerlIO layers, what happens if the file doesn't exist yet, etc.

    use File::Replace 'replace2'; my ($infh,$outfh) = replace2($filename); while (<$infh>) { # write whatever you like to $outfh here print $outfh "X: $_"; } close $infh; # closing both handles will close $outfh; # trigger the replace

    Since I hope this is something that you might find useful, I would be happy about any feedback you might have!

    To give a practical example, here is an update of my code from this node. As you can see I was able to get rid of eight lines of fairly complicated code, while keeping the main loop entirely unchanged. The module also adds some more robustness, as it incorporates a few more checks on whether operations were successful or not.

Encoding Decoding on multiple formats RFC
No replies — Read more | Post response
by thanos1983
on Sep 19, 2017 at 06:44

    Hello fellow Monks,

    I am looking for your advice on updating and my implemented module for encoding and decoding multiple formats. I wrote the module and tried to include as many formats I could. I know that there other formats that I have not added but in my case during the encoding decoding process has to be also converted to hex and vise versa, where I found problems with more formats that I have not included on my sample of code.

    The whole idea behind the module, I am working for a telecommunication company and part of my daily job is to correct problems. The languages can vary globally since it is a live network with live customers and the format is in hex on a variety of encoding patterns. I had some cases that I had to create small scripts to process the packages before and after the nodes so I can observe encoding corruptions or not. Sample of previous questions that I was working that are similar with the module (Chinese to Hex and Hex to Chinese, Arabic to Hex and Hex to Arabic). After seeing my self that I need more and more encodings for more and more languages I end up saying that I need to write a simple module to do that for me instead of creating more or less the same code again and again.

    So having said that, sample of code as the user would use the module based on the encodings that can be handled:

    The actual module, that I still have not found a good name to apply. Any ideas for naming please feel free to propose.

    The module by it self is extremely simple, but at the same time on my position and for my colleagues is extremely useful. Any suggestions on code or any other improvement please feel free to suggest.

    Hope this tiny module will help others also.

    BR, Thanos

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Kindness and support for Meredith
No replies — Read more | Post response
by stevieb
on Sep 18, 2017 at 11:47

    This isn't about Perl; it's about the community.

    Early last week, I wrote in CB about a tremendously disturbing event that took place with my family.

    In response, several Monks reached out to offer condolences and offers of help.

    In my near absence from here since then, a bunch of Monks got together, and 1nickt reached out a few times to say that a group of Monks wanted to do something. Initially, I was advised that the offer could be in the form of finance for travel etc. After I carefully deliberated this kind gesture and discussed with my wife, I decided that I wouldn't feel comfortable taking any funds directly, so I let Nick know that it would be preferred to send flowers or donate to a charity instead.

    I was advised by Nick that a beautiful arrangement had been sent on behalf of the Monks, and any left over funds plus any more funds that may trickle in would be donated to some form of preventing violence charity. I advised Nick that I was too busy to deal with it, so I asked if he'd spearhead the decision of which one.

    I want to express my (and my wife's) deepest gratitude for such an overwhelmingly kind gesture by everyone involved; those who provided funding, as well as those who reached out to offer emotional support. I'd like to thank Nick directly as well for taking the time to organize everything he did.

    This goes to show that this is a great place of caring, not just another forum to get help with questions.

    Perlmonks is the only group I let in on what had happened, as it's the only online forum where I feel so comfortable, and people here came through with flying colours... the manner was absolutely unexpected; stunning actually.

    Thank you very much everyone, it's kind of hard to put into words, so instead, I'll just try to get back into the groove and give back the best way I can; by continuing to help those who need it here.



More Betterer Game of Life
1 direct reply — Read more / Contribute
by eyepopslikeamosquito
on Sep 18, 2017 at 03:11

    Without good design, good algorithms, and complete understanding of the program's operation, your carefully optimized code will amount to one of mankind's least fruitful creations - a fast slow program.

    -- Michael Abrash

    In High Performance Game of Life, I chose a very simple design, storing all live cells in a single set. Though pleasing for its simplicity and unboundedness, its drawback is that counting live neighbours becomes a hash lookup, a chronic performance bottleneck. What to do?

    Rather than spending more time optimizing my original design -- thus creating a "fast slow program" -- I researched the domain, learning of many different ways to do it. From the many possible approaches, I chose the simplest one I could find that looked interesting and enjoyable, and implemented it in pure Perl.

    To try to keep my initial attempt short and understandable, I started with a simplified version based on the the brilliant works of Adam P. Goucher (apg), tiling the universe with 64 x 64 tiles in a conventional way, each tile having eight neighbours. Note that this was chosen for simplicity; more efficient schemes are available, such as the "brick wall" tiling used by Goucher in later versions. For background on the concept of breaking the game of life universe into overlapping tiles, see this description of Life128 and vlife.

    My code is loosely based on apgnano (version 2) but advances one tick at a time (rather than two at a time, as apg did) and does not attempt to use universe history. Fair warning though. Despite striving to keep the code simple and short, it's way more complex than my original, swelling from 66 lines of code to 414.

    Benchmark Results

    I've updated the benchmark results given in my original node. As you can see, even this simplified version, with no attempts made at code optimization, is already an order of magnitude faster than the optimized version of the original.

    Version375K cells750K cells1.5 million cells3 million cells
    new (see below)1 secs1 secs3 secs6 secs (Mario improvements)13 secs26 secs52 secs108 secs (Original)35 secs70 secs141 secs284 secs
    Game::Life::Infinite:Board37 secs96 secs273 secs905 secs

    As for memory use, the maximum Windows Private Bytes used for the three million cell case by each process was:

    • New (see below): 700,000K
    • (Original): 1,455,004K
    • (Mario improvements): 1,596,368K
    • Game::Life::Infinite:Board: 18,138,504K

    Benchmark timings running AppleFritter's Lidka test for 30,000 ticks were:
    VersionLidka 30,000 ticks
    new (see below)58 secs (Mario improvements)450 secs (Original)1635 secs
    Game::Life::Infinite:Board640 secs

    Improving My Initial Attempt

    There is certainly plenty of scope for improving my initial attempt. After all, I have not attempted any optimizations at all, just tried to implement ideas from apg's C++/assembler programs in a pure Perl form in a simple and clear way. While all feedback is welcome, I'm especially eager to see:

    • Refactorings that make the Perl code shorter, clearer, more idiomatic.
    • Performance optimizations.
    • Explanations of (and alternatives to) the bit-twiddling code below, specifically the bit operations in st64_tiletick() below I find especially hard to follow.
    • Bug fixes. I was shocked when my code worked the second time I ran it - just one coding blunder was corrected before my new passed tgol.t, tgol2.t, tgol3.t and the 30,000 lidka test! So I suspect there may be more bugs lurking in this brand new implementation.
    As a minimum, any code refactorings should be tested by running tgol.t and tgol3.t from my original node. Note that this new version of is (or should be) 100% interface compatible with my original.

New Monk Discussion
How to get raw node content
2 direct replies — Read more / Contribute
by roboticus
on Sep 15, 2017 at 14:25

    Hello, gang:

    I was wondering if there was an API available that would let me fetch the raw content of a perlmonks node?

    Every once in a while, I see a node that I'm interested in dismantling, but it gets a bit butchered by the HTMLification/templating/(or something). The latest example is Reaped: Re: .pl to .exe, where I'm wanting to figure out just what the code is doing. But with the HTML entities, font rendering and whatnot, I can't really tell exactly what the code *was*. So rather than hand-editing it and trying to put it in a form that I can analyze, I'd love to be able to occasionally fetch just the raw node contents.

    I did a little googling and trying to browse the SiteDocClan nodes, but I'm not a member, so there's a limit to what I can see (e.g., I can't see sdc to-do wiki, SDC Wiki, the PMDev, editor, cabalist and pedagogue wikis...).

    I've found some public information, like What XML generators are currently available on PerlMonks?, WWW::PerlMonks, but I didn't see anything that provides the raw node content. I'm not asking for a new feature if it's not available, just a pointer to it if it exists.



    When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2017-09-20 11:39 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (236 votes). Check out past polls.