Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

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
[emacs] dual files mangling Perl and Lisp code?
2 direct replies — Read more / Contribute
by LanX
on Sep 19, 2017 at 04:15
    Hi

    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...

    update

    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:

    "DLDtest.pm 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:

    dldtest.fcgi

    #!/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;

    DLDtest.pm

    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
    Update:
    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, "create_account.pl" which spits out this error:

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

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

    I even tried to change it to:

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

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

    my $newdbpw = $pb->generate($newpw);

    so...do 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/Struct.pm.

    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.

    F.
    use strict; use warnings; use Data::Dumper; use Win32::API; use Win32::API::Callback; use Convert::Binary::C; #use experimental 'bitwise'; =for comment https://www.reddit.com/r/perl/comments/1i13h7/win32api_and_user32setwi +neventhook_help/ https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs +.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs +.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs +.85).aspx http://code.activestate.com/lists/perl-win32-users/22434/ =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
by fefofe@gmx.ch
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
    Log::Log4perl->init($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 ...
Semantic diff for Perl code
3 direct replies — Read more / Contribute
by LanX
on Sep 14, 2017 at 15:23
    Hi

    Colleague asked me if I knew a method to compare modules where functions blocks where moved.

    My first idea was to extract functions (probably with PPI or B::Xref ) and to diff them individually.

    The next idea only to extract sums from the different blocks...

    Than it occurred to me that a "semantic diff" could be a nice help for version control comments, and could also provide informations of other forms of refactoring. *

    Any ready to use projects available?

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

    *) found this in the mean time explaining the idea http://martinfowler.com/bliki/SemanticDiff.html

Custom prompts for Net::Appliance::Session
1 direct reply — Read more / Contribute
by edimusrex
on Sep 14, 2017 at 12:20

    Before I begin I have posted a similar question to the following https://serverfault.com/questions/873672/custom-prompt-using-netappliancesession

    So what I am trying to do is create a custom login prompt for my cisco smart switch. The prompt expected for the username/password is

    User Name: Password:

    So I've created the following prompt file containing :
    prompt username match /User Name/ prompt password match /Password/

    My script code looks like this :

    #!/usr/bin/perl use warnings; use strict; use Net::Appliance::Session; my $host = '<my_host>'; my $user = '<my_user>'; my $pass = '<my_pass>'; my $session = Net::Appliance::Session->new({ add_library => '/home/edunn/switch', personality => 'custom', transport => 'SSH', host => $host, connect_options => { opts => [ '-q', ], }, }); $session->set_global_log_at('debug'); $session->connect($user,$pass ) or die "Cannot Connect! : $!"; my @output = $session->cmd('show version'); $session->close; print join("\n",@output);

    When I run the script I get the following error

    [0.001442] p finding prompt [0.006910] t creating Net::Telnet wrapper for ssh [0.007164] t command expands to: ssh -o StrictHostKeyChecking=n +o -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -q 192.168.2.17 [1.349082] d SEEN: [1.364935] p reading phrasebook /home/edunn/switch/custom/login [1.365581] p storing prompt username [1.366753] p storing prompt password [1.367592] p nope, doesn't (yet) match password [1.367821] p nope, doesn't (yet) match username [1.368008] p no match so far, more data? [1.368295] d SEEN: [1.368446] p nope, doesn't (yet) match password [1.368690] p nope, doesn't (yet) match username [1.368877] p no match so far, more data? [1.384701] d SEEN: User Name: [1.384963] p nope, doesn't (yet) match password [1.385179] p hit, matches prompt username [1.385931] p prompt has been set to (?-xism:User Name) unknown prompt [prompt] at /usr/share/perl5/vendor_perl/Net/CLI/Intera +ct/Phrasebook.pm line 53 Net::CLI::Interact::Phrasebook::prompt('Net::CLI::Interact::Ph +rasebook=HASH(0x3665390)', 'prompt') called at /usr/share/perl5/vendo +r_perl/Net/CLI/Interact/Role/Prompt.pm line 48 Net::CLI::Interact::Role::Prompt::prompt_looks_like('Net::CLI: +:Interact=HASH(0x329dc78)', 'prompt') called at /usr/lib64/perl5/vend +or_perl/Moose/Meta/Method/Delegation.pm line 108 Net::Appliance::Session::prompt_looks_like('Net::Appliance::Se +ssion=HASH(0x31d6d30)', 'prompt') called at /usr/share/perl5/vendor_p +erl/Net/Appliance/Session/Transport.pm line 58 Net::Appliance::Session::Transport::connect('Net::Appliance::S +ession=HASH(0x31d6d30)', 'cisco', 'uzf1IgENudObn759sJ9U') called at . +/switch.pl line 21

    If I am looking at this correctly it appears to be successfully identifying the User Name and the Password prompts but dies at unknown prompt prompt at /usr/share/perl5/vendor_perl/Net/CLI/Interact/Phrasebook.pm line 53. No sure what the expected value prompt is or where it is coming from.

    As always, any and all help will be greatly appreciated

    **** UPDATE ****

    I ended up updating the firmware to the switch which added the ability for user authenticated ssh so I no longer have the need to look for quirky prompts and can now use the Net::Appliance::Session module without a hitch. Thank you all for suggestions.

New Meditations
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.

    Cheers,

    -stevieb

More Betterer Game of Life
No replies — Read more | Post response
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, Organism.pm 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 Organism.pm (see below)1 secs1 secs3 secs6 secs
    Organism.pm (Mario improvements)13 secs26 secs52 secs108 secs
    Organism.pm (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 Organism.pm (see below): 700,000K
    • Organism.pm (Original): 1,455,004K
    • Organism.pm (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 Organism.pm (see below)58 secs
    Organism.pm (Mario improvements)450 secs
    Organism.pm (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 Organism.pm 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 Organism.pm 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.

    Thanks!

    ...roboticus

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

Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
[shmem]: unbelievable. ergo insurance germany offers a contract: paying 1.5 euro a day over 18 years, they ensure a payback of 7.501 euro
[shmem]: *if* there is a bonus due, they would pay 9.250
[shmem]: don't expect anything noteworthy from a countrie's elections in which such things are shrugged off.
[shmem]: otoh, hindering me from spending the money before due time is worth some fee, isn't it?

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2017-09-19 15:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (222 votes). Check out past polls.

    Notices?