http://qs321.pair.com?node_id=19724
Intrepid's user image
User since: Jun 24, 2000 at 20:36 UTC (24 years ago)
Last here: Jan 07, 2022 at 03:06 UTC (2 years ago)
Experience: 2561
Level:Deacon (12)
Writeups: 207
CPAN ID:SOMIAN
Location:Buffalo CITY / New York STATE / U.S.A. NATION / North American CONTINENT / Western HEMISPHERE / Terra PLANET / Sol SYSTEM / MilkyWay GALAXY / "local" GROUP / Virgo SUPERCLUSTER
User's localtime: Mar 28, 2024 at 06:56 EDT
Scratchpad: View
For this user:Search nodes
Watch for posts by this user

about this image:
This is a visual fingerprint (a "visprint" as it's called) — an image generated using fractal maths — representing my GnuPG key fingerprint (postprocessed in ImageMagick).

Welcome to the home node of The Unreasonable Man! (Soren 'Tino, "somian", Soren Andersen)

“The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man.” — George Bernard Shaw

Other Favorite Quotes

"[André Malraux said] Do what you believe you must and leave the interpreting of it to others."
"[This] seemed to me to summarize his personal philosophy. How true this is. Don't be distracted by the carping of bystanders, their irresponsible attitudes, their self-serving, cowardly words and actions."
— Daisaku Ikeda on a dialog with André Malraux

A little quote about religious tolerance, which I see as pertaining to the tendency of some Christians to shout "Persecution!" rather often nowadays:

"We respect the right of everyone to believe whatever they like. ... But there are two important limits to religious tolerance. First, I have no right to legal protection against your scepticism, criticism or ridicule. Religion is too powerful a force, and is too often a cause of injustice or evil, for it to be immune from discussion and debate."
David Pannick QC

“Perl is the portable distillation of the UNIX philosophy."
— Scott McMahan

"Write documentation as if whoever reads it is a violent psychopath who knows where you live."
—Steve English, as quoted by Peter Langston


You can disagree with my views about Perlmonks, surely,

but do not say later that you didn't have access to those views, carefully explained ;-]>
What else is on this node? [an erratic, partial TOC]
I use multiple Operating System / Platforms and therefore several different ports of Perl. last update 28 Dec 2011
Interesting CPAN modules: stuff I want to check out when I find the time.  
"Tricky" for me to remember how to use: An assortment of Perl topics that I need to look up excessively often. last update 02 Mar 2005
My GPG public key  
Our Solemn Intonement -- something to be mindful of.  
Some things are more important than Perl: a short rant. last update 08 Aug 2004
The syntax-highlighted rendition of a snippet offered in Perl Monks' Meditations. last update 04 Jul 2004
Shell s‎crip‎ting in service of Perl: download and view PM nodecode. last update 07 Aug 2003
Terribly kewl CSS scheme for Perl Monks. last update 02 Sep 2004
I learned some Perl and became a CPAN Author:
[...]AUTHORS/ID/S/SO/SOMIAN/

"... people who condemn others simply on the basis that the target of condemnation is "angry" or "frustrated" are using a false premise as a basis for their condemnation. Anger is not, by itself, a transgression against society, or the Monastery."

The most reasonable of suggestions has been made in Dealing with An(?:no|on)ytroll by tirwhan. It deserves serious thought.


Building CPAN modules my way

I've got my own approach to building CPAN modules for use on my Debian-based systems (generally a known, stable target).


You will see formatting oddities on this node. These show as visible HTML formatting tags. The reason is not carelessness; instead, after this node was created, the parser for Perlmonks nodes changed such that style=... in tags is no longer accepted.

A short rant

One thing that I've noticed in my time spent chatting in the cb here at Perlmonks is that the level of ethical sophistication amongst a few of my fellow cb'ers can be terribly low. I make this generalization because there's one prime point of all ethical systems that I can feel any respect for, and that is:

Might does Not make Right
But it is clear that among the cb'ers are those who don't understand this. They have an enormous blind spot when it comes to issues in the workplace or the Perl (or other kind of) hacker community. Maybe it's a generational thing; I'm in my 40s and many Monks are in their 20s. I think the times are shaping young people to have much lower sensitivity to this. Most are very quick to point out the shortcomings of political leaders but very few seem able to see that abuse of privilige and power plays a big role close around them in their everyday lives.

There are two kinds of social power generally at work in our world:

Both these exert their influence generally (not always) to the detraction of good in the lives of human beings, to the enhancement of evil. People seem to regard the exercize of power by individuals like irc ops as some form of divine right, which is fine as long as such people who think this way don't try to pass themselves off as freedom-loving people. Furthermore: there seems to be a general assumption that if a person has contrary views to an irc #channel-op or a Perlmonks God, they are automatically wrong. This is childish, immature, dangerous and pathetic.

Just as bad is the pattern wherein supposedly intelligent people automatically assume that the person saying a new thing that insults (in their view) or challenges a comfortable dogma, or other item of "social consensus," is automatically wrong.

The only positive change that has ever taken place in the world has come about because of alienated, despised malcontents who dared to speak truth to power. The only kind of human being truly worth honoring is one who can summon the personal courage to speak truth to power, on whatever level or in whatever form it takes (embodied as either the despot or the mob). No-one lives a worthwhile life without ever falling afoul of some embodiment of power, sometime during their lives. The rest of humanity live like sheep, and no society that deserves to be remembered by history erects monuments of honor to sheep.

When a person gets banned in irc or otherwise "punished" somehow in any kind of hacker social context, they fairly often deserve it because their actions have been contrary to the general good of the group. But not always. This distinction between "always" and "not always" is the difference between the destruction of the world and its salvation. It is everything. Not understanding this is the distinction between an ignorant person and a real citizen, whether of the Happy Realm of Hacking Free Software or of the World.

From the Wikipedia entry for Internet Troll we see this quote:

[Likewise,] accusers are often motivated by a desire to defend a particular Internet project, and references to an Internet user as a troll might not be based on the actual goals of the person so named. As a result, identifying the goals of Internet trolls is most often speculative.

The use of the term "Troll" on Perlmonks by a certain group of people is an example of something like what's described above. It reflects not on the accused person but on the accusers, who are misusing a type of peer group -based power (being the Despotic Mob) to exercize coercion against someone whose aims are, as many others see, not those of a troll at all. The very best that can be said of such misuse is that the accusers are engaging in reckless and irresponsible speculation. The worst is that they themselves are far more despicable than any "Internet Troll", that they are in fact aiming to give themselves the twisted pleasure of seeing their group power effectively deny another participant the option of continuing to engage in a reasonable relationship with the site, community or project in question.

One can only feel pity for people living with the kind of impoverished inner lives and distorted emotional personalities that would derive pleasure from such a thing, but unfortunately the modern world at least, with its intense pressures and demands, often gives rise to such it seems.


I don't see posts by Anonymous Monk beginning at 6:30pm on 7 Dec 2005, by using CSS to override display settings. The texts of postings of any nature by any non-existing (Anonymous) Monk are invisible for me. This is a measure that I've taken until such time as the preferred solution comes to pass (the preferred solution being: the Perlmonks site no longer allows Anonymous posting at all).

A side note: The application at cb60 is the only cb history interface that is currently working (to my knowledge) at the time of this writing, and is the only one that can be configured to ignore users as the live chatterbox can.


There's a particularly annoying kind of conduct that very frequently takes place and lands users who commit it on the following list. This consists of coming into the chatterbox with a minimal but strange-sounding question - one that rings "warning bells" for some of the experienced Perl users. When it is suggested that more information is needed because the approach seems dubious (perhaps based on a mistaken understanding of how something in Perl works), such an individual committing this type of annoyance then leaves in a huff, saying something like Thanks for the kind help in a sarcastic and injured way that is intended to cause guilt feelings.

This is playing the "Newbie Victim of Mean Monks" card, and it is not only stupid, and not only pathetic, but also wrong - because the chatterbox or Perlmonks in general is a place where many give of their time to try to help less experienced Perlers. These volunteers don't need to put up with that kind of childishness, the attempted emotional manipulation and tantrums; and in my opinion, should not put up with it.

Again, it is (in my opinion), really ok to insist on minimum standards of mature behavior in order to qualify for help or attention at Perlmonks.


Perl Tips, Observations, and Experiments


I use both Free Software Operating Systems and the proprietary Microsoft Windows OSes.

Obviously I prefer to spend more time on the former (my favorites are Ubuntu and its parent distribution, Debian). On MS Windows I use both ActivePerl and the new Win32 Perl that's being called StrawberryPerl. I often build my own Perl installations from source, as well.

The quality of the user experience one has with the MS Windwoes OSes is highly variable. Some users find little lacking in it and some are driven crazy by it. One inclination that is not well-served by Microsoft is the desire to use the CLI (Command-Line Interface, but if you are here reading, you knew that ;-) …and so I rely on the long-lived and community-supported Cygwin environment (this is important: Cygwin is supported by volunteers; do not act like a petulant spoiled brat if you go asking for support {if you happen to try Cygwin out}; if you do, you will just be ignored). Cygwin provides a port of Perl that tracks the major release cycle of mainstream Perl and "acts like" Perl running on a unix OS platform. Cygwin also provides the Bash shell and many other GNU userspace components that are common to all GNU/Linux and other free unix OSes.

Because I have acquired years of experience using Perl on MS Windwoes, I do not have the oblivious outlook about file name extentions that is customary from users who do only work on unix platforms. My decision is to name Perl programs with a .plx extention which disambiguates these files from those containing Perl library code. I use the appropriate MS Windows commands (from the CMD.exe cli) to create the right Registry settings so that the files named with .plx extentions are associated with the perl executable.

A smattering of Useful Tips for PerlMonks, especially new ones

Ripped off from busunsl's node:

Link types at PM (because I tend to forget :-):


Monks Solemn Intonement:

righteousness () { perl -e' print "The troublesome entities, irksome to Monks:\n " , ( join " and ", map{ sprintf qq{$_ is safe as }.q{&#}.qq{%d;}, ord ; } qw/[ ]/ ) , "\n"; ' }


n.y.p.m.blue

– my PerlMonks color theme for CSS-supporting browsers – is now listed and maintained on this node.

This list is of modules that I'm not currently using for anything but that I think I might want to at some future time


A little parts bin of useful HTML entities for doing PM node markup

"["      left  sq brkt            [      [
"]"      right sq brkt            ]      ]
"<"      left  angle brkt         >      &#60; or &lt;
">"      right angle brkt         <      &#62; or &gt;


"mdash"  em-dash                  —    &#8212;
"ndash"  en-dash                  –    &#8211;
"lsquo"  left  single quotation   ‘    &#8216;
"rsquo"  right single quotation   ’    &#8217;

How I am creating ordinary paragraphs for Perlmonks node writeups these days:

sh-prompt $ perl -MText::Wrap='wrap,$columns' \ -MText::Textile=textile \ -lp000we \ 'INIT{$columns=78} s{\cM?\cJ} [ ]g; $_=wrap(q[],q[ ],textile($_)).$\;' DRAFT.TMP

This should work fine in a MS Windows CMD shell too, with the alterations that (a) all single quotes around the -e s‎crip‎t and perl flags are changed to double quotes, and (b) the line-continuation backslash/newlines are removed.


·Assorted Perl Stuff, and platform-specific notes·


Which and where is “Some::Perl::Module
(finding VERSION and location of a Perl module):

Preface:

Depending on your OS and your work habits / preferences, you might want to use a Unix sh means of wrapping the Perl code implementing this technique (second thing below), or you might need a MS Windows console helper (in the form of a DOSKEY macro, shown immediately below). I've named this critter different things in different manifestations on different machines at different times ... but now I am aiming to settle on it being named PMTEST.

PMTEST=perl -le "do{$modn=$_;s!::!/!g;$_.=q[.pm];do{print qq[$modn is +not installed.];next} unless eval qq#require(\"$_\");1# && !$@;$modv= +defined(${$modn.q[::VERSION]}) ? ${$modn.q[::VERSION]}:q{[version und +efined]};$numtyp=2>$modv=~tr/.// ?'%s':'% 6d';printf qq[ %-*s $numty +p in %s\n],(length>30 ? 5+length:15+length),$modn,$modv,$INC{$_}}for +@ARGV;" $*

Sorry, those long (wrapped) ugly pieces of code are what's required for MS Windows CMD shell. The command interpreter does not offer any means (that I have discovered) of using continuing statements on multiple lines when defining a DOSKEY macro. Don't try a COPY-PASTE of the above, either, or you'll have to figure out how to remove every introduced newline inside the macro definition before the code will work. Trust me, you won't feel good about the wasted time.

To use the above code, you must place it in a *.bat or *.cmd file and then "execute" it from the MS Windows console (the commandline interface, CLI, CMD.exe).

Invoke the macro (not the .bat file it was saved in, which you execute only once per each shell session or instance) with a single arg, the Perl-style name of a module (for ex. “pmtest CGI” or “pmtest File::Find”).

Here's the Unix shell (bash/ksh etc.) rendition of the pmtest thing

# pmtest: bash reusable function authored by Soren Andersen # license/terms of use/modification/redist: same as Perl pmtest () { perl -e' my$modn = my$mod = "'$1'"; $mod =~s@::@/@g; $mod.=q[.pm]; die ("module $modn not installed.\n",$@) if ! eval {require qq[$mod];}; my $modv = defined ${$modn.q[::VERSION]} ? ${$modn.q[::VERSION]} : q{[version undefined]}; my$numtyp= (2 > $modv =~tr/.//) ? "%s" : "% 6d"; printf " %-*s $numtyp in %s\n", length($modn) > 30 ? 5+length($modn) : 15+length($modn), $modn, $modv, $INC{$mod}; '; return 0 }

This also needs to be "gotten into" the bash session somehow. Ths canonical way of doing so is to include the above in a shell initialization file like ~/.profile or ~/.bashrc.


For contemplation by people who want to write software installers, Perl installation administrators, etc.:

In contrast with Unix-like platforms, MS Windows has it's own sense of Well-known Folders (not absolute filesystem "folders" but instead pointers to locations which can reasonably be expected to exist on most Windows machines, with some divergence between the bog-ordinary Workstation and the more complex Server kind of Windows installation).

These are abstractions, meta-directories if you like, which exist above the level of the actual filesystem and happen to be represented in the typical, default Windows ENV by variables like %APPDATA% and %ProgramFiles% and %ALLUSERSPROFILE%.

We can access the values assigned to these meta-directories using the API calls wrapped in the Win32.pm module (not in the core namespace which is automatically built in when Perl is created for a Windows system; the user has to explicitly say use Win32; in order to make this work).

Here's a simple one-liner to demonstrate:

perl -MWin32 -le "my @ds=grep {/CSIDL_/} @{ [keys %Win32::] }; do {printf qq/%31s => %s\n/, $_, Win32::GetFolderPath(&{$Win32::{ +$_}}) } for map { $_->[0] } sort {$a->[1] <=> $b->[1]} map { [$_,&{$Win +32::{$_}}] } @ds"
Note that we did not even need to know the particular names of the metadirectories available on the specific version of Windows on which this is run, which is Kinda Cool imho.

Here's a way to get the location of the meta-directory of your choice, assuming that you choose with some clue to begin with ;-/ ... :

perl -MWin32 -le "my @ds=grep {/^CSIDL_/ && /\U$ARGV[0]/} @{ [keys %Wi +n32::] }; do {printf qq/%31s => %s\n/, substr($_,6), Win32::GetFolderPath(&{$ +Win32::{$_}}) } for @ds" profile
This should display the Special Folders that are named *PROFILE* (in globbing terms) and display the actual location(s) of such folders.

Note also that the above commandlines aren't broken up in actual use, and will have to be mended by any who wish to try it out. MS Windows CMD shell doesn't allow multi-line commands even inside quotes UPDATE: You can create multi-line Perl one-liner (console input) s‎crip‎ts in the interactive Windows CMD shell. You will escape the newline with the ^ character (caret) but this does not work to span lines inside quotes. Instead, you will use -e repeatedly, just as you may do in a *nix sh-type shell. Here's the oneline demo above, thanks to pKai who educated me on this!:

perl -MWin32 -e "my @ds=grep {/CSIDL_/} @{ [keys %Win32::] };" ^ -e "do {printf qq/%31s => %s\n/, substr($_=>6), Win32::GetFolderPath(& +{$Win32::{$_}}) }" ^ -e "for map { $_->[0] } sort {$a->[1] <=> $b->[1]} map { [$_,&{$Win32: +:{$_}}] } @ds"

Here's a DOSKEY macro-ized version of the code above. Handy for interactive CMD shell use where you need to quickly check the list of Special Folders (or a particular group of them).

:: MS Windows BAT/CMD syntax. Wraps a Perl one-liner program. DOSKEY SPECIALFOLDERS=perl -MWin32 -e "my @ds=grep {/CSIDL_/} @{ [key +s %%Win32::] }; do {printf qq/%%24s=>%%s\n/, substr($_=>6), Win32::GetFolderPath( & +{$Win32::{$_}} )} for map { $_->[0] } grep {(0+@ARGV ? $_->[0]=~m<$ARGV[0]>i : 1) +} sort {$a->[1] <=> ${b}->[1]} map { [$_,&{$Win32::{$_}}] + } @ds" $*
Remember to reformat the code above so that no linebreaks are present. The line that begins with DOSKEY needs to be one continuous line.

·For MSWin -using Monks·


Documentation for the current version of PPM (3), the crufty thingy that many MSwin users rely on to install new packaged Perl modules:
ppm3 Documentation
  • You can easily break your PPM v3 unknowingly merely by updating Text::Autoformat – see Bug Listing
  • PPD file format – appears to have not been updated since the 5.6 series releases at ActiveState. Please note that it makes no mention whatsoever of a parameter or field named ARCHITECTURE NAME then go and in contrast look at some example .PPD files from the various repositories.

    Note Added:
    This seems to be explained by this brief excerpt from the ppm Mailing List, authored by Jan Dubois:

    "Since Perl 5.6 and Perl 5.8 are not binary compatible, we started appending the Perl version number to the architecture string in ActivePerl 5.8. Try this:
         <ARCHITECTURE NAME="MSWin32-x86-multi-thread-5.8" />
    
    Both ppm2 and ppm3 in ActivePerl 8xx have been patched to use these architecture names."
  • A (perhaps) little-known, rich PPM repository to add to your list that ppm searches.
  • For Perl5.8 you may check status of ActiveState's builds of packages (modules).
  •  

    The dmake utility:

    The recommended tool for building Perl from the source kit using a Free C/C++ compiler (MinGW), is dmake. This variant of the classic make tool is now maintained by OpenOffice.org folks ("tools" Project) and the dmake manpage is online.

    dmake on CPAN: is now maintained by Steve Hay and is no longer the extremely old code offered years ago by Gurusamy Sarathy. Steve is building it using MSVC++ from the OO.org source mentioned above.


    ·For EveryMonk· (any platform)


    Investigate the modules and libraries your Perl installation has access to:

    Tom Phoenix' s‎crip‎t "Inside" on CPAN.

    Need Help Using CPAN Effectively?

    Preflight-check for CPAN.pm mirrors (using system `ping(1)'):

    perl -MCPAN -l \ -e 'CPAN::Config->load;' \ -e '@pcnt= $^O eq "cygwin"? qw(-n 2):qw(-c 2);' \ -e ' do{ $fn=$_; if (s#^\w+p://([^/]+).*#$1#) { print $fn; system("ping",@pcnt,$_); print "\n","-"x52 } } for @{ $CPAN::Config->{urllist} }' # code tested on cygwin and GNU/Linux

    Find your system's master list of CPAN mirror sites, maybe freshen it up:

    perl -MFile::stat -MCPAN -MLWP::Simple=mirror -le 'CPAN::Config->load; + my $fhost;' \ -e 'my $Mdat = $CPAN::Config->{keep_source_where}.q[/MIRRORED.BY];' +\ -e 'if (-e $Mdat and -M _ < 14) { print qq[$Mdat: freshness OK, last + modified: ]' \ -e ' .gmtime stat($Mdat)->mtime()' \ -e '} else { ($fhost)=grep(/^http/,@{$CPAN::Config->{urllist}});' \ -e 'die "no suitable cpan http mirror host" if !$fhost;' \ -e 'printf q[%s],qq[File $Mdat not found or stale, will d/l fresh fr +om $fhost ...];' \ -e 'mirror($fhost .q[MIRRORED.BY] , $Mdat) and print q[ ].gmtime(sta +t($Mdat)->mtime)}'

    Wrap the code above in a function in your shell initfile if you are a bash user and you like to have such conveniences at your "fingertips", as I do:

    function mirrorsrefresh { < above perl code here > }

    More tips on coping with CPAN.pm can be found here at "dumpcpanurls" Snippet.


    Easy way to see that s‎crip‎t output gets a terminating newline automatically:

    In s‎crip‎ts:
    #! /usr/bin/perl -l # *or* $\ = "\n"; # do it once and won't have to again.
    In one-liners (s‎crip‎t is "-e"):
       $ perl [other flags] -le "[some code]"

    Filter newlines out of systems call results

    %hash = ( key => grep [ chomp ], `which ps` ); which does the same things as: %hash = ( key => grep {chomp || 1} `which ps` );

    Attribution: seen on comp.lang.perl.misc in msgid <3F447BDB.9928761A@acm.org>.

    Slurp an entire file in

    # Previous declaration of "$filename" is assumed. my $data = do{local(@ARGV,$/) = $filename;<>}

    Attribution: here

    Another way to do this, faster and better:

    my $data = do{ open local(*FH),$filename or die "can't open: $!" ; sysread( FH, my $buf, -s FH ) ; $buf ; };

    Something that may be called "The Bartian Transposition" someday:

    (@a[0 .. ($#a = $#b)], @b) = @{[ @b, @a]} # swap two arrays

    Where's my HOME???

    my $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7] || die "WAAAAA! I'm HOMEless!\n"; # from `perldoc perlop'.

    Something really special:

    Opcode scanning for Safe.pm

    Dump a string of opcode names that can be fed to Safe::new->permit. Based on knowledge / shell elan shared by ysth.

    $ perl -MO=Concise,-exec <FILENAME.pl> \ | perl -lnaF -e '$_=$F[2]; s/\W.*//; $h{$_}=0; END{ print join " "=>k +eys %h}'

    Created 30 Jul 2003 EDT (GMT+4):
    Updated Thu Jul 31 2003
    Updated Sun Jul 04 2004
    Regarding the Meditation on List Cleanup

    [After getting helpful advice on the node above I rewrote the snippet (as a complete s‎crip‎tlet) ... several times (mostly recently on July 4 2004)]

    The goal is to eliminate duplicates without disturbing existing ordered-ness. Thus the property of mundane hash assignment such that duplicates disappear is not sufficient by itself, but in a combination demonstrated in this code below, the truth-ness of a hash value can be used to prevent duplicate array entries.

    #! /usr/bin/env perl
    # "uniqnord" - remove dups from a list of identifiers.
    use strict; use warnings;
    
    $, = ! -t STDOUT ? "\n" : " " ;
    my %seen = (); $\ = "\n";
    print STDOUT  join($, =>
        grep {!$seen{$_}++} map {
          if (/ +/) { $/=" " ; @_=split }
            else    { chomp ; $_ }} <>)
    __END__
    
    The real code:
    #! /usr/bin/env perl # "uniqnord" - remove dups from a list of identifiers. use strict; use warnings; $, = ! -t STDOUT ? "\n" : " " ; my %seen = (); $\ = "\n"; print STDOUT join($, => grep {!$seen{$_}++} map { if (/ +/) { $/=" " ; @_=split } else { chomp ; $_ }} <>) __END__