Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"


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

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
RFC: Continuous Integration (CI) for your CPAN modules (for free!)
3 direct replies — Read more / Contribute
by stevieb
on Jan 15, 2016 at 11:31

    This guide will attempt to explain the basics of using a version control system (specifically GitHub), along with other free online tools to automate your builds and generate test coverage reports automatically on each update to your code.

    It'll be a work in progress for some time (very high level overview at this time), so feel free to leave comments for fixes/updates etc. This doc assumes that you already have module code you've written (eg: My::Module). There's a fair amount of detail lacking because I can't remember the exact steps for everything, but over the weekend, I'll re-run the entire process and fill in the large gaps here.

    First, head on over to GitHub, and sign up for a free account, and create a repository (eg: my-module).

    Now, install git, and clone your newly created (empty) repo to the local machine:

    git clone

    From the directory above your actual module code, copy the contents of the module's top level dir into the new empty repo dir:

    cp -R My-Module/* my-module

    Add these files to git, and perform your first check-in:

    cd my-module git add . git commit -am "initial import" git push

    You now have revision control for every change you make going forward to your module.

    Next, head over to Travis-CI, and sign up for an account with your GitHub username. After signed in, 'sync' your account to github, and in your repositories screen, you'll see an on/off toggle for your new repository. Enable it.

    Now go to Coveralls and perform the same task you did for Travis.

    At this point, everything should be enabled and ready for use. To proceed, you'll need to set up a .travis.yml file in your distribution's root directory. Here's one that I use in all of my modules. It's configured to run the build on perl versions 5.8 through 5.22, and it'll also perform test coverage in prep for sending to Coveralls.

    language: perl perl: - "5.22" - "5.20" - "5.18" - "5.16" - "5.14" - "5.12" - "5.10" - "5.8" os: - linux before_install: - git clone git:// ~/travis-perl-helpe +rs - source ~/travis-perl-helpers/init - build-perl - perl -V - build-dist - cd $BUILD_DIR install: - cpan-install Devel::Cover - cpan-install --deps - cpan-install --coverage before_script: - coverage-setup script: - PERL5OPT=-MDevel::Cover=-coverage,statement,branch,condition,path, +subroutine prove -lrv t - cover after_success: - cover -report coveralls - coverage-report matrix: include: - perl: 5.20 env: COVERAGE=1

    Note that Travis doesn't do testing on Windows, so I always advise having a Windows machine/VM handy, and run your test suite on there to ensure it runs cross-platform (if necessary) before upload to CPAN.

    Perform a change in your code, then commit and push it to GitHub. Now go to your Travis page (mine's for example), and your build should be running or just about to start.

    If all builds succeed, head on over to your Coveralls page (eg:, and you should see a page with your repos listed, with the coverage details of your unit tests.

    Click on the repository, and at the top of the page, click "Badge URLs". Copy the entire text that contains the HTML link. You'll need this, along with a Travis link for your repo to add to your POD documentation.

    *Note*: I can't remember where I got my own Travis link from, but yours will be the same as mine, simply replace the name of my repo with yours. See the example below...

    Now, in your POD, add a tiny bit of markup and paste in your new links. I put mine in the NAME section so it's visible immediately to visitors to my modules on CPAN:

    =head1 NAME Devel::Examine::Subs - Get info about, search/replace and inject code +into Perl files and subs. =for html <a href=""><img src="h +ttps://"/> <a href=' +h=master'><img src=' +-subs/badge.svg?branch=master&service=github' alt='Coverage Status' / +></a>

    This will result in two images in the NAME section of your POD when users view your module on CPAN. One will show the build success or fail, the other the percentage of test coverage you have.

    Here's an example of what this looks like. You can click through both images and get to the full details of both the build process, and the coverage results.


    • - only does line testing, so I always use Devel::Cover in conjunction to get even more detailed coverage
RFC: Installing DBD::Oracle on Mac 'el capitaine"
No replies — Read more | Post response
by Sandy
on Jan 14, 2016 at 16:09

    There are some specific issues with the new Mac operating system and oracle client. The information is 'out there' on-line, but the information is not all in one place.

    This is my tutorial on how to install DBD::Oracle. I make no claims that it is the 'only' way, but I checked (and double checked) and it seems to work.

    If it meets your exacting standards, I would like to move this to the tutorial section

    Installing DBD::Oracle on Mac (El Capitaine).

    I had a few issues when installing DBD::Oracle on El Capitaine, but eventually succeeded. I thought I would share my process, which may help someone attempting the same process.

    PS: I didn't figure this out all by myself, I would like to give credit to the blogs/tutorials listed in the reference section below


    1. Get Oracle client
      • download from:
    2. Install Oracle client
      • Create directory /Library/Oracle
      • copy previously installed zip files to this directory
      • unzip files
        cd /Library sudo mkdir Oracle sudo cp ~/Downloads/instantclient*.zip . sudo unzip sudo unzip sudo unzip
    3. Configure Oracle client
      • Create a /network/admin folder in instantclient_11_2
      • cd instantclient_11_2 sudo mkdir network sudo mkdir network/admin
      • Using a text editor, create tnsnames.ora in the network/admin folder
      • Be sure to replace hostname and SID with the appropriate data for your Oracle instance. network/admin folder. It should contain:
      • set environment variables. Edit ~/.bash_profile and add the following
      • ORACLE_HOME=/Library/Oracle/instantclient_11_2 DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Library/Oracle/instantclient_11_ +2 TNS_ADMIN=/Library/Oracle/instantclient_11_2/network/admin PATH=$PATH:/Library/Oracle/instantclient_11_2 CLASSPATH=$CLASSPATH:$ORACLE_HOME export ORACLE_HOME export DYLD_LIBRARY_PATH export TNS_ADMIN export PATH export CLASSPATH
      • or edit ~/.tcshrc (I don't use bash... :( )
      • # required for the Oracle Client setenv ORACLE_HOME /Library/Oracle/instantclient_11_2 if ($?DYLD_LIBRARY_PATH) then setenv DYLD_LIBRARY_PATH ${DYLD_LIBRARY_PATH}:$ORACLE_HOME else setenv DYLD_LIBRARY_PATH $ORACLE_HOME endif setenv TNS_ADMIN $ORACLE_HOME/network/admin setenv PATH ${PATH}:$ORACLE_HOME if ($?CLASSPATH) then setenv CLASSPATH ${CLASSPATH}:$ORACLE_HOME else setenv CLASSPATH $ORACLE_HOME endif
      • source your .bash_profile or .tcshrc file, or log off and then back on.

    4. Test Oracle Client
      • If this works, great!
      • [~] sqlplus -v SQL*Plus: Release Production [~]
      • If you get this error message,...
        dyld: Library not loaded: /ade/dosulliv_sqlplus_mac/oracle/sqlplus/lib +/libsqlplus.dylib Referenced from: /Users/sandy/Downloads/instantclient_11_2/sqlplus Reason: image not found
        then the DYLD_LIBRARY_PATH has not been set properly.
    5. Install DBD::DBI
    6. [~] sudo cpan Password: Terminal does not support AddHistory. cpan shell -- CPAN exploration and modules installation (v2.00) Enter 'h' for help. cpan[1]> install DBI

    Installing DBD::Oracle

    I had issues with this, so I did not use CPAN.

    1. Prepare:
      • download the tarball for DBD::Oracle

      • unzip and untar
        gunzip DBD-Oracle-1.75_2.tar.gz tar -xvf DBD-Oracle-1.75_2.tar cd DBD-Oracle-1.75_2
    2. prepare the make file:
      [~/Downloads/DBD-Oracle-1.75_2] perl Makefile.PL [... deleted stuff ...] Using DBI 1.634 (for perl 5.018002 on darwin-thread-multi-2level) inst +alled in /Library/Perl/5.18/darwin-thread-multi-2level/auto/DBI/ Configuring DBD::Oracle for perl 5.018002 on darwin (darwin-thread-mul +ti-2level) [... deleted stuff...] Installing on a darwin, Ver#15.0 Using Oracle in /Library/Oracle/instantclient_11_2 dyld: Library not loaded: /ade/dosulliv_sqlplus_mac/oracle/sqlplus/lib +/libsqlplus.dylib Referenced from: /Library/Oracle/instantclient_11_2/sqlplus Reason: image not found [... more deleted errors ...]
    3. Fixing dyld: Library not loaded: problem

      For some reason, the DYLD_LIBRARY_PATH environment variable is not being used/set correctly? (even though 'sqlplus' works)

      1. create a bash script with this content named "". (see reference 4 below for link to article which explains what this is doing)
        • Note that this is modified from what was shown in the reference 4 because "el capitaine" does not like "@executable_path". I changed to code to hardcode the paths to "/Library/Oracle/instant_client_11_2"
        #!/bin/sh # script to change the dynamic lib paths and ids for oracle instant cl +ient # exes and libs # proces all the executable files in this directory find . -maxdepth 1 -type f \( -perm -1 -o \( -perm -10 -o -perm -100 \ +) \) -print | while read exe do echo echo adjusting executable $exe baseexe=`basename $exe` otool -L $exe | awk '/oracle/ {print $1}' | while read lib do echo adjusting lib $lib baselib=`basename $lib` if [ "$baseexe" = "$baselib" ] then echo changing id to $baselib for $exe install_name_tool -id $baselib $exe else echo changing path id for $lib in $exe install_name_tool -change $lib /Library/Oracle/instantclie +nt_11_2/$baselib $exe fi done done
      2. Go to /Library/Oracle/instant_client_11_2, and run the script
        [/Library/Oracle/instantclient_11_2] sudo bash ~/myScrips// + Password: adjusting executable ./adrci adjusting lib /ade/b/3071542110/oracle/rdbms/lib/libclntsh.dylib.11.1 changing path id for /ade/b/3071542110/oracle/rdbms/lib/libclntsh.dyli +b.11.1 in ./adrci adjusting lib /ade/dosulliv_ldapmac/oracle/ldap/lib/libnnz11.dylib [... deleted stuff...]

  • Prepare makefile (again). You must run as administrator because the process will want to create a soft link in your /Library/Oracle/instant_client_11_2 directory.
    [~/Downloads/DBD-Oracle-1.75_2] sudo perl Makefile.PL Password: [... deleted stuff ...] Using DBI 1.634 (for perl 5.018002 on darwin-thread-multi-2level) inst +alled in /Library/Perl/5.18/darwin-thread-multi-2level/auto/DBI/ Configuring DBD::Oracle for perl 5.018002 on darwin (darwin-thread-mul +ti-2level) [... deleted stuff...] Looks like an Instant Client installation, okay You don't have a libclntsh.dylib file, only /Library/Oracle/instantcli +ent_11_2/libclntsh.dylib.11.1 So I'm going to create a /Library/Oracle/instantclient_11_2/libclntsh. +dylib symlink to /Library/Oracle/instantclient_11_2/libclntsh.dylib.1 +1.1 [...deleted stuff...] Writing Makefile for DBD::Oracle Writing MYMETA.yml and MYMETA.json
  • make
    [~/Downloads/DBD-Oracle-1.75_2] make cp lib/DBD/Oracle/ blib/lib/DBD/Oracle/ cp lib/DBD/Oracle/ blib/lib/DBD/Oracle/ cp lib/DBD/Oracle/Troubleshooting/Aix.pod blib/lib/DBD/Oracle/Troubles +hooting/Aix.pod cp lib/DBD/Oracle/Troubleshooting/Sun.pod blib/lib/DBD/Oracle/Troubles +hooting/Sun.pod [... deleted stuff ...] Manifying blib/man3/DBD::Oracle::Troubleshooting.3pm Manifying blib/man3/DBD::Oracle::Troubleshooting::Win64.3pm Manifying blib/man3/DBD::Oracle::Troubleshooting::Vms.3pm Manifying blib/man3/DBD::Oracle::Troubleshooting::Linux.3pm Manifying blib/man3/DBD::Oracle::Troubleshooting::Macos.3pm Manifying blib/man3/DBD::Oracle::Object.3pm Manifying blib/man3/DBD::Oracle::Troubleshooting::Win32.3pm
  • test (this fails on el capitaine, probably doesn't on earlier version of Mac ??)
    [~/Downloads/DBD-Oracle-1.75_2] make test PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_h +arness(0, 'blib/lib', 'blib/arch')" t/*.t t/000-report-versions-tiny.t .. # [... deleted stuff ... mostly version numbers of required modules ...] t/000-report-versions-tiny.t .. ok t/00versions.t ................ Can't load '/Users/sandy/Downloads/DBD-Oracle-1.75_2/blib/arch/auto/DB +D/Oracle/Oracle.bundle' for module DBD::Oracle: dlopen(/Users/sandy/Downloads/DBD-Oracle-1.75_ +2/blib/arch/auto/DBD/Oracle/Oracle.bundle, 2): Library not loaded: libclntsh.dylib.11.1 Referenced from: /Users/sandy/Downloads/DBD-Oracle-1.75_2/blib/arch/au +to/DBD/Oracle/Oracle.bundle Reason: unsafe use of relative rpath libclntsh.dylib.11.1 in /Users/sandy/Downloads/DBD-Oracle-1.75_2/blib/arch/auto/DBD/Oracle/Ora +cle.bundle with restricted binary at /System/Library/Perl/5.18/darwin-thread-mult +i-2level/ line 194. at t/00versions.t line 10. [... more errors ...]
  • fix "unsafe use of relative rpath"
    • Note that the path name of the Oracle.bundle would need to be changed to reflect your situation (check the error message for the exact location of the perl file it is complaining about)
    sudo install_name_tool -change libclntsh.dylib.11.1 /Library/Oracle/in +stantclient_11_2/libclntsh.dylib.11.1 /Users/sandy/Downloads/DBD-Oracle-1.75_2/blib/arch/auto/DBD/Oracle/Ora +cle.bundle
  • test again
    [~/Downloads/DBD-Oracle-1.75_2] make test PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_h +arness(0, 'blib/lib', 'blib/arch')" t/*.t t/000-report-versions-tiny.t .. # [... deleted stuff ...] t/000-report-versions-tiny.t .. ok t/00versions.t ................ # OCI client library version: t/00versions.t ................ ok t/01base.t .................... ok t/10general.t ................. skipped: Unable to connect to Oracle t/12impdata.t ................. skipped: Unable to connect to Oracle [... deleted stuff ...] All tests successful. Files=38, Tests=9, 8 wallclock secs ( 0.11 usr 0.06 sys + 6.33 cusr + 0.96 csys = 7.46 CPU) Result: PASS
  • install
    sudo make install

    My final test

    [~/Downloads] cat #!/usr/bin/perl use strict; use warnings; use DBD::Oracle; use DBI; my $user= "user"; my $passwd = "password"; my $dbh = DBI->connect("dbi:Oracle:ORCL", $user, $passwd); [~/Downloads] perl [~/Downloads]





  • Context, pedantry and appropriate response.
    6 direct replies — Read more / Contribute
    by BrowserUk
    on Jan 02, 2016 at 05:51

      Nit-picking pedantry is the bane of productive discourse.

      A not uncommon question in life is: "How much do you weigh"? To which we generally respond with something like: "nn pounds" or "nn kilos".

      Of course, if we last weighed ourselves naked having just stepped out of the shower, and we are currently wearing a full set of skiing gear; or if a holiday weekend or half a year has intervened, then our responses may be slightly or even wildly inaccurate. Which may or may not be okay depending on who is asking and why; but we generally know how much thought we should give to the accuracy and qualification of our responses from the context of the question.

      Of course, we don't really "weigh" what we weigh. We have a mass of a certain number of Newtons that only becomes a weight in the presence of a particular value of gravity.

      Ie. we 'weigh' differently on the surface of the Earth than we would on the Moon or in the ISS. And we would 'weigh' differently again if we were bridge of the Enterprise at Warp factor 10 and the inertial stabilizers failed.

      But no one ever responds to the target question with "nn Newtons"; or qualifies their "nn pounds/kilos" with "whilst naked, at a distance of nn miles/meters from the center of the Earth, whilst traveling at sub-relativistic speeds, and after a week or more of nominally average calorific intake and expenditure".

      And thank Dog they don't! Without we tailor and truncate our answers to the contexts in which the questions are asked, life would become quagmired in a treacle of inferable verbiage. And intolerable.

      Which is why mealy-mouthed, oneupmanship, pedantry posts like this deserve the response it got.

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.
    Stop Using Perl pt. 2
    5 direct replies — Read more / Contribute
    by sushi
    on Dec 29, 2015 at 00:01

      The Perl Jam 2: The Camel Strikes Back (32c3)

      Link to discussion of last year's talk: 1111750

      I cringed the first talk, but it seems like this talk is more productive. Summary:

      • Hashes and arrays are considered "secure" (???)
      • SQL injections happen when you don't sanitize input (not exactly groundbreaking)
      • Results from various CGI-like modules are not standardized
      • Real bug in example code
      • <> does strange things when given something other than a file (strange to anyone who hasn't memorized the camel book)
      • open() creates a file descriptor unless it's used with | in which case it executes
      I sincerely hope there will not be a Stop Using Perl pt 3. I can only handle someone complaining about list flattening for so long.
    XML::Simple needs to go!
    7 direct replies — Read more / Contribute
    by Preceptor
    on Dec 21, 2015 at 05:18

      If there's one module that I think really needs to get thrown out of CPAN, it's this one. Why? Well, generally I'm forgiving - don't like a module; don't use it. Problem is - XML::Simple is false advertising - it commonly gets installed because it's "Simple", and that's simply not the case at all.

      I see a steady stream of questions - both here and on Stack Overflow - about this module, because someone's been tripped up again by how this module tries to coerce a more complex data structure into a less complicated one.

      That's really the root of the problem - just like parsing HTML with regex - the approach is fundamentally flawed.

      You can use regex to grab a value out of HTML/XML. It's nasty and brittle, but sometimes a dirty hack is expedient.

      And the same is true, I contend, of XML::Simple - it's the 'parsing with a regex' sort of solution. In that it can sort of work, in some scenarios but pretty fundamentally it's a bad solution to the problem at hand.

      But were the module called anything else this wouldn't be a problem. There's a lot of stuff in the CPAN namespace that I've never used or installed - that's fine, that's kind of the point.

      But many an unwary newbie has been caught out by it - there are a number of "Simple" modules that offer cut down interfaces for a limited subset of operations. LWP::Simple is a good example - it offers a cut down interface to the basic tasks one might need to accomplish with LWP.

      This module is official discouraged in it's module doc page but it's still picked up as the "Simple" answer.

      Is there precedent for renaming a module in CPAN? I know it's not really an option to just delete it, because there's probably some legacy code depending on it (as much as I think they should be rewriting it, that isn't really my call to make!). But it really does suffer from all the things that have given perl a bit of a bad name in the past - it's a sure road to some rather hacky/nasty code.

    Yak Shaving for Fun and Profit (or How I Learned to Stop Worry and Love Perl 6)
    1 direct reply — Read more / Contribute
    by raiph
    on Dec 16, 2015 at 13:02

      This post is about Perl 6, not rock solid Perl 5

      Today's Perl 6 advent calendar looks like it may be of more than average interest to monks interested in the sort of thing -Ofun meant in 2015 when trying to write a non-trivial Perl 6 application: Yak Shaving for Fun and Profit (or How I Learned to Stop Worry and Love Perl 6)

      Trolls are expected to join our meditation. Herewith a collective "happy winter solstice" hug for them all from me and on behalf of a bug-eyed butterfly. I ask that those of us that prefer to don the robes of a monk rather than dress up as trolls do their very best to leave the trolls alone or just surround them with genuine unconditional love. Imagine how cool it would be if there were no attacks in this thread, or, more realistically, there were no responses to attacks no matter how personal or pernicious. Thanks for your cooperation. :)

      And finally, here's another happy (near) winter solstice greeting, this time for the whole monastery. I learn a lot about being humble and encouraging my compassionate self in posts here and I appreciate this gift that keeps giving.

    What the HEY is up with the cartoon butterfly for "Perl 6" ?!
    14 direct replies — Read more / Contribute
    by 1nickt
    on Dec 07, 2015 at 08:10

      Yes, this is a rant. I'm trying to rant less. But this is something I feel have to say, in the admittedly faint hope that it will reach the ears of someone in charge.

      Today I went to look at "Perl 6." The Perl Weekly newsletter has been turning more and more into a promotional rag for "Perl 6," and then I saw that a good deal of the London Perl Workshop has been dedicated to it. So, after 20 years more or less of programming perl, I figured I should at least swing by and see what all the distraction is about.

      Lo and behold when I get to the website of the "plucky little sister of Perl 5" (who wrote this marketing pablum, a 20-yr old Communications major?), I am greeted by a multicolored butterfly that looks like it belongs on the Disney Channel early-afternoon lineup.

      What the HEY?!

      Are you out of your MIND?

      In the interests of keeping this rant short, I'll just say that if you were trying to convince serious programmers that "Perl 6" was worth any of their time to investigate, you could not have chosen a less effective design. To me this kindergarden art symbolizes:

      • shallowness
      • infantilism
      • dumbing down to try to widen the appeal
      • the ascendency of communications-major type people over critical thinkers and engineers
      • Microsoft Windows (remember the paper clip?)
      • the complete lack of seriousness of "Perl 6" as a programming language
      and so on.

      I write Perl for a living, for companies that use it to do business and make money. It's serious stuff, and it's fun because of how challenging it is, not because of a pink and purple anthropomorphic icon.

      To the "Perl 6" people: I was already very skeptical of your project, given its debaculous history. Well, now I am convinced. You could not have done more to prove to me that, as I suspected, it is a vanity project of a handful of the brightest, most bored Perl 5 gurus, that has no application in the real world in which I live and program.

      To be clear, your butterfly has turned me off from even beginning to read the content of your site, and I would imagine that I am very far from being the only one.

      (Note: I looked for a place on the "Perl 6" website to post this as feedback, but no such link was to be found.)

      Larry Wall would be rolling in his grave. Oh, wait ...

      But for the rest of you, if you were that bored, couldn't you have just gone off quietly and tackled some new field of human endeavour if you were "over" Perl, like, for example, how tchrist became the arbiter of all aspects of the English language on Stackexchange? Why the need to try to "rebrand" Perl as a consumer product for millenial schoolgirls?

      Can't Perl users file a class-action suit or something to force the Butterfly People to pick another name for their hobby?

      The way forward always starts with a minimal test.
    OO APIs and FP interfaces
    3 direct replies — Read more / Contribute
    by Apero
    on Dec 03, 2015 at 20:05

      I'm interested in opinions on the use of FP (functional-Perl, ie: non-OO) routines exposed to consumers of an otherwise OO-module. Given that this is almost completely a style preference, I've chosen to Meditate on it. See the concept code below for an idea what's involved. While the examples are terse, the idea is to expose package-configs, possibly defaults to constructor use, or any package-wide tuning a module may support.

      As I see it, there are 3 potential options:

      1. Use FP routines, and document public API use as Ex::Mod::conf(key=>'value')
      2. Use OO-style syntax, and document public API use as Ex::Mod->conf(key=>'value')
      3. Avoid such use all-together, making the caller always list every option desired.

      #1 above is what my code samples use, and seems to best represent what the routine does. On the other hand, callers now need to remember if they're invoking an FP routine verses a method/constructor.

      #2 is basically the same, but lets consumers be lazy and use the infix operator in all cases. This might be written in the module as:

      sub conf { shift; # throw away unused class. # .. do real work here }

      #3 would make callers always provide every default option (or not have any say in configuring other package-level adjustments.) Perhaps the callers re-use lengthy/common constructor arguments like so:

      my %re_use = (name => 'Alice'); Ex::Mod->new( override=>'whatever', %re_use );
      I'm not really fond of making callers do extra work if it's considered likely that use of a particular library might wish to set sensible defaults throughout use of the module. Further, this means package-config (not used by constructors) could only be adjusted by reaching into something like $Ex::Mod::DefaultTimeout to enact changes, which also feels messy.

      Below is the example consumer, and the example Ex::Mod class:

    Looking for CPAN module author: Daniel Yacob (String::LCSS)
    1 direct reply — Read more / Contribute
    by toolic
    on Nov 30, 2015 at 21:59
      UPDATE: 2015 dec 30, I am now a co-maintainer. I was unable to contact the author, but I was granted permissions by the powers that be.


      Does anyone know of a way to contact Daniel Yacob, the author of the CPAN String::LCSS module?

      I am at step 4 of the PAUSE procedure for taking over a module ("Try posting in public places such as ...").

      I have tried to contact the author by sending emails to 3 addresses. I have not received any positive replies.

    Tree Structure Challenge
    5 direct replies — Read more / Contribute
    by choroba
    on Nov 29, 2015 at 18:29
      At work, I needed to fix logging of changes in a tree structure. The language was unfortunately Java, but I started with a Perl prototype to test the approaches and border cases. The Java solution was more challenging for me, but the Perl implementation was still interesting enough to share. For those bored or interested, I present the problem below. The original domain was different, but I'm probably not allowed to speak about it outside of the firm.

      We'll use the famous animal tree:

      Reptile - Snake - Python - Cobra - Lizard - Salamander - Chameleon - Bird - Pigeon - Canary - Owl Mammal - Equine - Horse - Zebra - Pony - Canine - Dog - Fox - Wolf - Bovine - Cow - Bison

      All the leaves are on the same level.

      Let's have a module which implements the following methods:


      Static method. 'Zoo'->Parent($node) returns the parent of the given node in the tree, e.g. 'Zoo'->Parent('Owl') is 'Bird', 'Zoo'->Parent('Bird') is 'Reptile'.


      The constructor. Use a list of tree leaves as arguments:

      my $zoo = 'Zoo'->new(qw( Cobra Pigeon Zebra ));


      For a given object, returns the list it was constructed from (order is not guaranteed).

      print join ' ', $zoo->get_leaves; # Cobra Pigeon Zebra

      The Task

      When comparing too different zoos, we aren't interested in the animals only, but in their categories, too. Our task is to implement a static method 'Zoo'->diff($zoo1, $zoo2) which returns two array references, $add and $delete, such that:

      1. Imagine we build trees above both of the objects, containing all their $_->get_leaves and their ancestors.
      2. If we start from the tree built above $zoo1, add all the nodes from $add and remove all nodes from $delete, we get $zoo2.
      3. Both the lists @$add and @$delete are minimal.

      For example,

      'Zoo'->diff( 'Zoo'->new('Cobra'), 'Zoo'->new('Fox') )

      should return

      ( [qw[ Fox Canine Mammal ]], [qw[ Cobra Snake Reptile ]] )


      'Zoo'->diff( 'Zoo'->new(qw( Dog Fox Wolf )), 'Zoo'->new(qw( Fox )));

      should return

      ( [], [ 'Dog', 'Wolf' ] )

      Updates: Please, use <readmore> tags for the code.

      Use only the documented API in the solution (i.e. Parent and get_leaves). The tree structure is not accessible directly (in reality, it was stored in a database).

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
    Pi Zero
    5 direct replies — Read more / Contribute
    by hippo
    on Nov 26, 2015 at 05:22

      The Pi Zero is out today. While nobody can predict the future it is certainly a possibility that this could be a huge deal in terms of the next generation of programmers. In order to help them to get the best start possible there ought to be a big effort to allow the installation of perl on this little box of tricks in a way that is as simple and fault-tolerant as possible for the novice.

      Is this a realistic goal? I do hope so. With the demise of Java this could represent the best opportunity to avoid another single-language-fits-all monopoly over the next 20 years.

      Caveat: I know next to nothing about RaspberryPi so far and the Pi Zero may even come with perl bundled already, in which case feel free to call me a numpty. However, I would rather raise awareness and be thought foolish/ignorant than let this go by without having tried to do something to raise awareness. I will be trying to track down one of these little wonders for my own edification (as no doubt will quite a few of you) and it would be great to be able to flex Perl's muscles on such a potentially ubiquitous platform.

      If you have any good links to Perl on the Pi, please reply. Thanks, Hippo.

    Something that bugs me about the Numeric class hierarchy in Perl 6
    1 direct reply — Read more / Contribute
    by grondilu
    on Nov 24, 2015 at 03:16

      Hello Monks,

      This is something that has bugged some times to times : I have the feeling that the class hierarchy for numeric types in Perl 6 is upside down.

      Let me give you an example. The other day I wrote on rosetta code the following function to compute binomial coefficients:

      sub infix:<choose> { [*] ($^n ... 0) Z/ 1 .. $^p } say 5 choose 3;

      I was quite happy about it, until I realized that the output was of type Rat, not Int. So I had to make an explicit conversion:

      sub infix:<choose> { ([*] ($^n ... 0) Z/ 1 .. $^p).Int }

      That was a bit annoying. Frankly, I expect something like 10/5 to be an integer, not a rational. I mean, I know it is a rational, but it also is an integer. Because normally in math, all integers are rationals. Their denominator is just 1.

      Things don't work like this in Perl 6. Numeric types are more about implementation than mathematics. Yet there is a feature in Perl 6 that could be used to make things work more like in math:

      subset Int of Rat where [%%] *.nude;

      If Int was defined as such, integers would be particular cases of rationals. In the same way, real numbers would be special cases of complex numbers:

      subset Real of Complex where { $_ == .conj };

      An other possibility would be:

      role Int does Rational { method nude { self, 1 }; ... }

      Or something like that, I don't know. Neither do I know if it would be possible or desirable to rewrite the whole Numeric hierarchy. Maybe it would not be worth the effort. But I do find it annoying that an Integer is not a Rat, or a Real not a Complex.

    "Indirect" object syntax?
    3 direct replies — Read more / Contribute
    by muba
    on Nov 22, 2015 at 21:30

      Disclaimer: IANAL. I am not a lawyer linguist.

      The syntax of (for example) $cgi = new CGI; is called indirect object syntax, which is also said to be in the dative case. Are these actually the correct designations?

    eval error stack
    2 direct replies — Read more / Contribute
    by shmem
    on Nov 11, 2015 at 16:13

      There's the perl special variable $@ which is set at eval errors. It is a global variable, and it is a SCALAR type variable. It gets easily clobbered if you don't proceed with utmost care (tye wrote some nodes about that) and fails to report the really interesting thing, e.g. in nested evals. Consider:

      my $foo = eval { my $bar = baz(); if ($@) { die "baz failed!\n"; } }; die $@ if $@; sub baz { eval "1 = 2"; } __END__ baz failed!

      With that code, there's currently no way to get at the real problem, which is in the baz code, where $@ is set to

      Can't modify constant item in scalar assignment at (eval 1) line 1, at + EOF

      and gets clobbered by my $foo = eval {...} Of course, the above program would have reported the baz() error, if baz()behaved well:

      sub baz { my $result = eval "1 = 2"; die $@ if $@; $result; }

      Nonsensical assignment reported, but where is the error from my $foo = eval { };? Looks like I have to set up a die signal handler, or some such. This is all very confusing and doesn't DWIM.

      And you cannot rely on $@ being propagated properly, unless you revise any included code that uses eval, which is pretty much anything, because eval is the heart of any perl code. All perl code is somehow evaled.

      Back to $@ - a SCALAR. Why don't we have @@ as an error stack, and a builtin %@ hash keyed upon the names of the stack frames (e.g. Package::sub or 'eva123') or such?

      The variables @@ and %@ currently (well, I have perl v5.18.2) work as a regular array/hash. But *@{SCALAR} isn't related to $@ at all.


      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
    Building the Right Thing (Part III): Customers
    1 direct reply — Read more / Contribute
    by eyepopslikeamosquito
    on Nov 01, 2015 at 01:37

      After introducing Lean startup in the last episode, this installment focuses on good ways to communicate with customers.

      Don't do what customers say they want, understand their problems and solve them.

      -- Per Haug Kogstad (Tandberg founder)

      Problems, Products and Markets

      Most startups begin with a brilliant new product idea. Most startups fail. While pulling an ingenious new product idea from your lower torso may work on occasion, a more systematic approach is to perform a sober analysis of the following three aspects:

      • A problem is the reason people want your product. Is it a big enough problem for people to pay you to solve it?
      • A product is the way you solve the problem. Are you capable of solving the problem? How do you know if you've found the "best" way to solve the problem? Are there other ways to solve it?
      • A market is a group of people who might want to buy your product. Who wants the problem solved badly enough to buy your product? Can you build a sustainable business in this market?
      Perhaps the worst way to answer these questions is to ask the customer what they want.

      A more promising approach is to observe and listen to the customer, so as to gain a deep understanding of their problems. Focus on their big problems, the ones they'll be glad to pay you to solve.

      You need to differentiate between cool and interesting problems and real problems for real people. Laura Klein gives some examples:

      • Word processors solved the problem that it was tough to edit something once you've typed it.
      • GPS navigation solved the problem that we are likely to get lost when away from our homes.
      • Angry Birds solved the problem of delivering pleasure hormones to our brains while waiting for a train.
      Admittedly, this is hard to predict and there is no guarantee of success. Is playing Angry Birds while waiting for a train really a vital problem? While there is no guarantee of success, and yes, most startups fail, early validation of product ideas ensures you fail as cheaply as possible, allowing you more shots at success.

      Customer Interviews

      Justin Wilcox suggests you start by asking your customer two introductory questions:

      • How do you describe your role?
      • What does success look like for you?
      With that context clarified, ask the following five questions:
      • What's the hardest part about <your problem context>?
      • Can you tell me about the last time that happened?
      • Why was that hard?
      • What, if anything, have you done to solve that problem?
      • What don't you love about the solutions you've tried?
      Notice that we are trying to steer away from hypothetical questions, in search of genuine problems that might be used to start a new business or grow an existing one.

      After the customer interview, you need to go away and figure out if you can build a solution to any of their big problems.

      Solution Interviews

      Rather than pitch a proposed solution to the customer with a demo that ends with them saying: "Thanks very much, we'll get back to you", Wilcox recommends doing a Solution Interview instead.

      • Don't start with a demo!
      • Pick the big problems from the customer interview that you think you can solve. Restate the problem; for example, I heard about this problem you have. Is that right? You need confirmation that you've properly understood their problem.
      • Propose a potential solution. Honestly ask for feedback. What do you think about this solution? Initiate a two-way discussion.
      • Finally, now we agree we've got the right problems, and we think we can solve them together, what do we need to do to make progress? What are the next steps? Make a to-do list with the customer.
      The general idea is not to pitch your solution, rather to engage the customer, build trust, build a partnership.

      User Testing

      If the Solution Interview went well, build a prototype solution (MVP) and observe the user interacting with it. Don't fall into the trap of building a broad MVP that is crappy and unusable. Instead, build a usable, but limited, version of your product.

      Laura Klein gives some tips on how to get good feedback from customers, based on years of watching mistakes made by folks lacking a user-experience background:

      • Shut the hell up. You want their opinions, not your own. You also need to give them more time than you think to figure things out on their own.
      • Don't give a guided tour. Let the user explore a bit on his own. Then give the user as little background information as possible to complete a task.
      • Ask open-ended questions. The more broad and open-ended your questions, the less likely you are to lead the user and the more likely you are to get interesting answers.
      • Follow up. For example, if the user says "that was cool", follow up and ask precisely why that was cool. Don't assume you know what makes a product cool.
      • Let the user fail. This can be painful, especially if it's your design that's failing. You're not testing if a person can be shown how to use a product, you're testing to see if a person can figure out how to use the product.

      Quantitative vs Qualitative research

      Quantitative research, for example A/B testing or Funnel analysis, measures what real people are actually doing with your product. It's statistically significant.

      Qualitative research, for example customer interviews and observing users and understanding their behavior, gives important insights, but is not statistically significant.

      Quantitative research tells you what. Qualitative research tells you why. You need both.

      Miscellaneous Tips

      Some general tips taken from a talk by Atlassian Product Manager Sherif Mansour on Building the right thing:

      • Distill customer interviews and customer conversations into a manageable set of Personas. Make these personas visible to everyone (Atlassian even stick them in the toilets).
      • Ask why. Understand why.
      • Find the root of the problem.
      • Understand the problem.
      • Define the solution.
      • User Journey Mapping. Shows end to end flow of a persona using a feature, starting with installation.
      • Get the user journey right (e.g. map out how someone enters/exits a feature).
      • Fake it till you make it. They use a variety of Pretotyping techniques as discussed in episode one; e.g. recording videos and showing to customers to elicit feedback.
      • Get feedback before you start (fake to validate you are building the right thing).
      • Choose carefully (beware domino effect).
      • Tell your story. Before you start. Build your box (hero shot, pitch and three pillars).
      • Assume no docs. This changes how you build your solution.

      Perl Monks References

      External References

    Add your Meditation
    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (4)
    As of 2016-05-01 07:59 GMT
    Find Nodes?
      Voting Booth?

      No recent polls found