A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Bash: How to loop through a list of terms containing spaces

Change the Internal Field Separator (IFS):

O=$IFS
IFS=$(echo -en "\n\b")
for f in $(ls *)
do
echo "$f"
done
IFS=$O

Perl debugger basics

start the debugger with perl -d script.pl

  • n - next step
  • s - step into
  • c - continue
  • b 100 - break at line 100
  • b sub - break at sub 'sub' (must be in the right file)
  • { v - display the surrounding lines before each step
How could I do p "-" x 100; v in one step?
  • w $var - watch variable $var (displays changed $var and stops)

XSL data types

http://www.zvon.org/xxl/XSL-Ref/Tutorials/Built-in-Types/bt1.html

<xsl:stylesheet
xmlns:sch="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
exclude-result-prefixes=" sch">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:variable name="a" as="sch:integer" select="12"/>
<xsl:variable name="b" as="sch:float" select="12.123456789123456789"/>
<xsl:variable name="c" as="sch:double" select="12.123456789123456789"/>
<xsl:variable name="d" as="sch:decimal" select="12.123456789123456789"/>

</xsl:stylesheet>

Subversion basics

# checkout / create a new project
svn checkout https://example.googlecode.com/svn/trunk/ example --username [username]

# submit a directory for the first time
svn import newdir/ https://example.googlecode.com/svn/trunk/

# see all modified files in project
svn status -v

# submit modified files
svn commit

# diff
svn diff --diff-cmd diff -x -wB [filename]
svn diff --diff-cmd diff -x --side-by-side [filename]

# move or copy, keeping history
svn mv [old file] [new file]
svn copy [old file] [new file]

# update your workspace to head
svn up /your-workspace

# update your workspace to a particular date
svn up -r {2010-11-14} /your-workspace

# ignore a file or directory
svn propset svn:ignore [file or dir] [parent dir]

Parsing HTML with Perl

HTML::Scrubber has replaced HTML::Sanitize

XML::LibXML has a parse_html method and a toString method.

Debugging XSLT

...is not fun:

<!-- DEBUG -->
<xsl:if test="$debug">
<xsl:message><xsl:text>--------</xsl:text></xsl:message>
<xsl:message><xsl:text>FUNCTION display-pagination-links:</xsl:text></xsl:message>
<xsl:message><xsl:text>--------</xsl:text></xsl:message>
<xsl:message><xsl:text>direction: </xsl:text><xsl:value-of select="$direction"/></xsl:message>
<xsl:message><xsl:text>link_type: </xsl:text><xsl:value-of select="$link_type"/></xsl:message>
</xsl:if>

less features

less 394 has ability to backspace on '/' search line

vim features

7.0.237 has highlighting of the text for which you're searching.

Basic CSS

* basics
#id = ID (mnemonic: I'd like some *hash*)
.class = class (mnemonic: polka *dots* are classic and classy)

* margin direction:
top right bottom left
(clockwise, starting from top)

* comments
/* this is a comment */
// this is not a comment!

* debugging
border: 2px solid red !important
or
display: none !important

* specifying elements:

html:
<ul id="list">
<li>
<div class="d1">one</div>
<div class="d2">two</div>
<div class="d3">three</div>
</li>
</ul>

css:
#list li div.d1 { //css }

--------------------------
http://robertnyman.com/2007/10/18/dont-over-specify-your-css-code/

/* Instead of this: */
div#container p.pre-amble{
margin-top: 1em;
}

/* Write it like this: */
.pre-amble{
margin-top: 1em;
}

/* Or like this: */
#container .pre-amble{
margin-top: 1em;
}

/* Instead of this: */
div#container div#header ul#navigation li{
float: left;
}

/* Write it like this: */
#navigation li{
float: left;
}

/* Or like this: */
#header #navigation li{
float: left;
}

XSLT math

Using math in XSLT: http://www.xml.com/pub/a/2001/05/07/xsltmath.html

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:template match="numbers">
A. 4 + 3.2 = <xsl:value-of select="x + y"/>
B. 3.2 - 4 = <xsl:value-of select="y - x"/>
C. 4 * 3.2 = <xsl:value-of select="x * y"/>
D. 11/3.2 = <xsl:value-of select="z div y"/>
E. 4 + 3.2 * 11 = <xsl:value-of select="x+y*z"/>
F. (4 + 3.2) * 11 = <xsl:value-of select="(x+y)*z"/>
G. 11 mod 4 = <xsl:value-of select="z mod x"/>
H. 4 + 3.2 + 11 = <xsl:value-of select="sum(*)"/>
I. floor(3.2) = <xsl:value-of select="floor(y)"/>
J. ceiling(3.2) = <xsl:value-of select="ceiling(y)"/>
K. round(3.2) = <xsl:value-of select="round(y)"/>
L. 11 + count(*) = <xsl:value-of select="11+count(*)"/>
M. 3.2 + string-length("3.2") =
<xsl:value-of select="y + string-length(y)"/>
N. 11 + "hello" = <xsl:value-of select="z + 'hello'"/>
</xsl:template>

</xsl:stylesheet>


Warning With some XSLT processors, the use of decimal numbers may introduce a tiny error. For example, the "3.2 - 4" in this example comes out as "-.7999999999999998" on some processors. While being off by .0000000000000002 isn't much, being off at all shows that math is not XSLT's strong point.

Display output of XSL transformation using PHP

Use XAMPP or similar to serve (reportedly works on PHP 5):

<?
$query = $_GET['q'];
$filePath = 'http://source-server:8889/page/'.$query;

$xslDoc = new DOMDocument();
$xslDoc->load("http://localhost/xslt/page_render.xsl");
$xmlDoc = new DOMDocument();
$xmlDoc->load( $filePath );

$proc = new XSLTProcessor();

$proc->importStylesheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
?>

Screen capture for long pages in firefox

The Firefox add-on Aviary is a very powerful screenshot program that can easily capture a really long web page as an image.

No XSLT2 in PHP

There is only one known xslt2 processor called SAXON (http://saxon.sourceforge.net/), built by Michael Kay, which was released for the Java and .NET platforms.

Other XSLT processors, including Sablotron, Xalan and MSXML, have not yet adopted xslt2.

Kay writes: "implementation [for xslt2 in php] does not exist because no-one has written one". He continues, "The usual workaround I recommend is to implement XSLT 2.0 transformation as a (Java-based or .NET-based) REST web service, and for the php application to submit transformation requests to that web service by means of HTTP requests. An alternative is to use a php-Java bridge"

Michael Kay manages an email-based discussion group called MulberryTech, a good resource for learning XSLT techniques (both 1 and 2). (http://www.mulberrytech.com/xsl/xsl-list/)


Don't display dynamic elements until page has loaded

<head>
<script type="text/javascript">

function getRefToDiv(divID,oDoc) {
if( document.getElementById ) {
return document.getElementById(divID); }
if( document.all ) {
return document.all[divID]; }
if( !oDoc ) { oDoc = document; }
if( document.layers ) {
if( oDoc.layers[divID] ) { return oDoc.layers[divID]; } else {
//repeatedly run through all child layers
for( var x = 0, y; !y && x < oDoc.layers.length; x++ ) {
//on success, return that layer, else return nothing
y = getRefToDiv(divID,oDoc.layers[x].document); }
return y; } }
return false;
}

function toggleDiv(divID_as_a_string,action) {
//get a reference as above ...
myReference = getRefToDiv(divID_as_a_string);
if( !myReference ) {
//window.alert('Nothing works in this browser');
return; //don't go any further
}
//now we have a reference to it
if( myReference.style ) {
//DOM & proprietary DOM
if (action == 'on') {
myReference.style.visibility = 'visible';
} else {
myReference.style.visibility = 'hidden';
}
} else {
//layers syntax
if (action == 'on') {
myReference.visibility = 'show';
} else {
myReference.visibility = 'hide';
}
}
}

function start() {
toggleDiv('slider','on');
}

window.onload = start;
&lt/script>
</head>

<body>
<div id="slider" style="visibility: hidden">
</body>

(If, Then, Else) LOGIC in XSL

Syntax:
<xsl:if test="XXX">
<!-- do something -->
</xsl:if>

<xsl:choose>
<xsl:when test="XXX">
<!-- do one thing -->
</xsl:when>
<xsl:when test="YYY">
<!-- do another thing -->
</xsl:when>
<xsl:otherwise>
<!-- do default thing -->
</xsl:otherwise>
</xsl:choose>


Logic examples:
<xsl:when test="matches(sql:feedurl_id, '^(\d+)$')">
<xsl:if test="$canonical-urls/agg:canonical-url[text()=$canonical-link-href][1]/@module = $module-type">
<xsl:when test="$module-type = 'knowledge'">
<xsl:when test="$module-type='iplayer' or $module-type='schedule'">
<xsl:if test="$debug">
<xsl:when test="document('')//this:modules/this:module[@type=$module-type]/this:merge-feeds">
<xsl:if test="position()=1">
<xsl:if test="position()=3 and count(agg:module)=0">
<xsl:when test="starts-with($name,'profile') or starts-with($name,'weather')">
<xsl:when test="starts-with(@type,'profile')">
<xsl:when test="@type='weather'">
<xsl:when test="count($modules/agg:modules/agg:module[starts-with(@type,'profile')])>0">

Histogram with perl

perl -lane'($i) = $F[4] =~ m{(\d+)\.}; $m=100; $s=10; for ($c=0; $c<=$m; $c+=$s) { if (($i >= $c) && ($i < $c+$s)) { $h{$c}++; } };END{ for ($c=0; $c<=$m; $c+=$s) { print "$c : ".("#" x $h{$c}); }}'

$i = the value with which you want to make a histogram

$h = hashref holding the histogram data
$s = histogram step size
$m = maximum histogram value

$c = loop counter

Cocoon XSLT errors

java.lang.NullPointerException

This could mean you've used the wrong attribute name in a tag, e.g.
<xsl:attribute type="type">
instead of
<xsl:attribute name="type">

There seems to be no syntax checking to warn in cases like this.

Basic Javascript

if( document.getElementById ){
var myReference = document.getElementById('divID');
}

XML::Validator::Schema

#!/usr/bin/perl

use XML::SAX::ParserFactory;
use XML::Validator::Schema;
# create a new validator object, using foo.xsd
$validator = XML::Validator::Schema->new(file => 'foo.xsd');
# create a SAX parser and assign the validator as a Handler
$parser = XML::SAX::ParserFactory->parser(Handler => $validator);
# validate foo.xml against foo.xsd
eval { $parser->parse_uri('foo.xml') };
die "File failed validation: $@" if $@;

The problem is:

Validating with XML::XPath

use XML::XPath; # update: use XML::LibXML and XML::LibXML::XPathContext instead
use Test::More qw(no_plan);

my $id = 298;
my $xml = &get_url("/$id")->{xml};
my $xp = XML::XPath->new( xml => $xml );
my $r = '/feed'; # root
ok( $xp->exists($r), "there should be a feed" );
ok( $xp->exists("$r/id"), "there should be a feed ID" );
ok( $xp->find("$r/id") =~ m{/$id}, "feed ID should be correct" );
ok( $xp->exists("$r/link[\@rel=\"self\"]"), "rel=self attr is correct" );
ok( ($xp->find("$r/link")->get_nodelist)[0]->getAttribute('href'), "href link exists" ); # this is ugly
check( $xp->find("$r/updated") => like => qr/^\d{4}\-\d\d\-\d\dT\d\d:\d\d:\d\d\.\d+Z$/ );

my $entries = $xp->find("/feed/entry"); # find all entry sections
ok( $entries, "there are entries" );
if ($entries->size) {
my $e = "/entry";
foreach my $node ($entries->get_nodelist) {
# it's bloody stupid transforming the XML::XPath object to a string and then parsing back to an object
# instead maybe loop through each node in the list using xpath [0] [1], etc?
# But why should I have to hack around this....
my $entry = XML::XPath->new( xml => $node->toString );
ok( $entry->exists("$e/title"), "title exists" );
}
}

# Conclusion: XML::XPath is bad for writing tests.

Crontab format (V3)

MAILTO=me@there.co.uk

# minute (0-59),
# | hour (0-23),
# | | day of the month (1-31),
# | | | month of the year (1-12),
# | | | | day of the week (0-6 with 0=Sunday).
# | | | | | commands
# 3 2,3,4 * * 0,6 /command to run on more than one day/hour
# 3 2,4-7 * * 1-5 /another/command to run on a range of days/hours

04 10 * * * /command/here 2>> /path/to/log/prog.$(date +\%Y\%m\%d).log

NOTES:
  • You must escape percent signs with a backslash
  • Putting them in double quotes doesn't work
  • Putting in double quotes and backslashes works, but the backslashes are written as part of the filename. So don't so that.

Perl test template

Comments: Logging may be mostly useful for debugging -- the log level can be raised for release.

#!/usr/bin/perl

#################################################################################
# Description of tests
#################################################################################

use strict;
use warnings;

use Test::More qw(no_plan);
use Test::Differences; # eq_or_diff()
use Test::Lazy qw/try check/; # check() displays the expected & actual upon failure, even for scalars
use Log::Log4perl;
use XML::Simple qw(:strict);

Log::Log4perl::init('conf/log4perl-test.conf');
my $LOG = Log::Log4perl->get_logger('log4perl.appender.LOGFILE');

$| = 1; select STDERR;
$| = 1; select STDOUT;

$LOG->info("Started tests");

use_ok('MyNamespace::MyModule');

dies_ok { MyNamespace::MyModule->new } 'fail to instantiate without parameters';

my $m = MyNamespace::MyModule->new( url => "foo", name => 'bar');
isa_ok($m, 'MyNamespace::MyModule');

How to find which function does what in Drupal 6

A forum post describes how to find the right function by hacking a core file.

In Drupal 6, inside the theme() function of /includes/theme.inc, change line 617 from this:

$output = call_user_func_array($info['function'], $args);

To this:

$output = '<!-- begin ' . $info['function'] . ' -->' . call_user_func_array($info['function'], $args) . '<!-- end ' . $info['function'] . ' -->' ;

The advice about not doing this on a production site stands.


Unix timezone settings

Time zone stuff in UNIX isn't difficult in concept but it can be tricky to work out how a box is configured.

The current timezone is set by the /etc/localtime file, which is either a symlink, or a hard link, or a copy of a file in /usr/share/zoneinfo. If the file's timestamp is a long time ago it's a fair bet it's been configured this way for a while.

The files in /usr/share/zoneinfo contain the definitions of a time zone -- its offset from UTC and any daylight savings in use. The problem is working out which file is in use. It could be a symlink:

[root@server ~]# ls -l /etc/localtime
lrwxrwxrwx 1 root root 27 Jun 26 2008 /etc/localtime -> /usr/share/zoneinfo/Etc/GMT

Given the timestamp on the symlink to the GMT zone file is June last year I'd say it's likely that it's been configured this way (ie, GMT) for a long time.

Other boxes don't have symlinked timezone files:

[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 1 root root 118 Mar 4 2008 /etc/localtime

They might have a hard link (which is like having a file known by another name -- same contents, more than one name) to a zoneinfo file. You can try to work this out using find:

[root@server ~]# ls -l /etc/localtime
-rw-r--r-- 11 root root 118 Apr 13 2009 /etc/localtime

[root@server ~]# find /usr/share/zoneinfo -samefile /etc/localtime
/usr/share/zoneinfo/GMT0
/usr/share/zoneinfo/Greenwich
/usr/share/zoneinfo/GMT
/usr/share/zoneinfo/Etc/GMT0
/usr/share/zoneinfo/Etc/Greenwich
/usr/share/zoneinfo/Etc/GMT
/usr/share/zoneinfo/Etc/GMT-0
/usr/share/zoneinfo/Etc/GMT+0
/usr/share/zoneinfo/GMT-0
/usr/share/zoneinfo/GMT+0

You can see here that /etc/localtime and all the GMT zone files are hard links to the same file contents -- ie, the file contents that set the time to GMT, showing this box is in GMT.

If /etc/localtime isn't a symlink or a hard link it must be a straight copy of a zone file (or it's totally broken). You can work this out by MD5 summing /etc/localtime's contents against all the possible time zone files it could be. Get the MD5 sum (like an abbreviation of the contents) of /etc/localtime:

[root@server ~]# md5sum /etc/localtime
fcccbcf95c718cf2fdee557763e460be /etc/localtime

Then find other files with the same contents:

[root@server ~]# find /usr/share/zoneinfo/ -type f -exec md5sum {} \; | grep fcccbcf95c718cf2fdee557763e460be
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/posix/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT+0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/Greenwich
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/Etc/GMT-0
fcccbcf95c718cf2fdee557763e460be /usr/share/zoneinfo/GMT-0

So it looks like this server's /etc/localtime has the same contents as all the GMT files. This box is in GMT.

Streaming mp3 on Ubuntu linux

sudo aptitude install vlc

FTP client for Linux and Mac

Filezilla is brilliant, and extremely fast.

Taxonomy menu for Drupal

<?php
$vid = 1; /* <---- put correct vocabulary ID here */
$terms = taxonomy_get_tree($vid);
print "<div class=\"item-list\">";
print "<ul>";
foreach ( $terms as $term ) {
$tcount = taxonomy_term_count_nodes($term->tid);
print "<li>".
l($term->name." (".$tcount.")",'taxonomy/term/'.$term->tid, array('title' => $tcount." posts in ".$term->name)).
"</li>";
} /* end foreach */
print "</ul>";
print "</div>";
?>

Linux package managers

  • rpm
  • yum
  • apt-get
  • aptitude

Install programs on linux in a local directory

No need for root access.

$ ./configure --prefix=/home/user/mypackages
$ make
$ make install

How to use Catalyst to automatically create Perl DBIx::Class modules

UNTESTED:

1. install Catalyst

2. pretend like you're going to create a catalyst app

catalyst.pl MyFakeApp

3.

cd MyFakeApp
./script/myfakeapp_create.pl model MyModelName DBIC::Schema \
MyApp::SchemaClass create=static dbi:mysql:... user password


http://search.cpan.org/~rkitover/Catalyst-Model-DBIC-Schema-0.29/lib/Catalys
t/Helper/Model/DBIC/Schema.pm



one I did earlier

perl ./script/tagindexer_create.pl model RequestDB DBIC::Schema
TagIndexer::Schema create=static
'dbi:mysql:database=request;host=[ip address];port=3306' tagindexer
tagindexer

Edit text files on remote linux servers

UNTESTED:

> I've never managed to figure out how to rig up editors to edit
> files on remote servers.

On the server, put this in smb.conf

[homes]
comment = Home Directories
hide dot files = yes
read only = No
browseable = yes


Then in the finder/windows explorer connect to 'smb://hostname/' . Then make an alias to it on your desktop.

Alternatively, TextWrangler on the Mac has an ftp/sftp browser.

http://www.barebones.com/products/TextWrangler/

Nested comments

Are your comments disappearing when you wrap them with a <xsl:comment> tag?

They may already be inside a comment.

Comma separated lists in XSL

<xsl:if test="position() != last()">

Lowercasing in XSL

translate(field_to_change, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz').

How to use PHP snippets in Drupal

Enable the core 'PHP filter' module, then select the PHP filter from the 'input formats' list when creating a page.

Using Java classes from XSLT under Coocon / JBoss

Possible MD5 methods:
<xsl:value-of select="md5:encode('$term')" xmlns:md5="java:org.jboss.security.Base64Encoder" />
<xsl:value-of select="md5:encodeString($term,'ISO-8859-1')" xmlns:md5="java:org.hsqldb.lib.MD5" />

Search through built-in classes in JBoss:
find /path/to/jboss-4.2.2.GA/server/default/ -name "*.jar" -exec jar tf {} \; | grep MD5 -H

Parents node's position in XSL

1. Count parents using <xsl:number>
Number can be extracted:
($n)=$c=~/(\d+)\.\d+\.\d+\.\d+$/;
and adjusted:
$n=((($n/2)-5)+1)

<xsl:number count="." level="multiple" from="/page" format="1"/>

Or with format="a", interpret like j=1, l=2, n=3, p=4, etc.

2. Count parents using position()
Simpler -- but apparently this is a weird way to do it. Probably inefficient too.

<xsl:value-of select="count(parent::*/parent::*/parent::*/preceding-sibling::*) - 3"/>

Read an internal Apache variable

...such as %{MY_MOD_OUTPUT_NOTE}n -- that would be available for logging, but not visible by mod_include.

RewriteEngine On
RewriteRule ^(.*)$ $1 [E=MY_MOD_ENV_VAR:%{ENV:MY_MOD_OUTPUT_NOTE}]

Apache: make file download instead of appear in browser

(Untested)

## FORCE FILE TO DOWNLOAD INSTEAD OF APPEAR IN BROWSER ###
-> http://www.htaccesselite.com/addtype-addhandler-action-vf6.html
AddType application/octet-stream .mov .mp3 .zip

Apache error "premature EOF in parsed file"

When Apache 1.3 says "premature EOF in parsed file".
What it means is "You've messed up the attribute syntax in a mod_include command".

Examples:

<!--#config timefmt=%s --> (no quotes)

<!--#set var='title' value='This title would've screwed things up' --> (apostrophe not escaped)

JSP/XSP generator in Cocoon

Warning: Untested.

In the sitemap.xmap:

<map:match pattern="^(\d+)$" type="regexp">
<map:generate type="serverpages" src="sfapi.xsp">
<map:parameter name="feedid" value="{1}"/>
</map:generate>

The source of sfapi.xsp

<?xml version="1.0" encoding="UTF-8"?>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp" xmlns:soap="http://apache.org/xsp/soap/3.0">
<results>
<xsp:logic>
int feedid=0;
try {
feedid = Integer.parseInt(parameters.getParameter("feedid"));
} catch (Exception e) {
feedid = -999;
}
</xsp:logic>

<soapcall
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
url="/FeedManager"
>

<m:getFeedData xmlns:m="http://else.something.co.uk/ns/feeds">
<int_1 xsi:type="xsd:int"><xsp:expr>feedid</xsp:expr></int_1>
</m:getFeedData>

</soapcall>

</results>
</xsp:page>

XSL to copy XML

Andy's way:

<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
</xsl:apply-templates>
</xsl:copy>
</xsl:template></xsl:output></xsl:stylesheet>


Another way:

<!-- copy the whole document -->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction">
<xsl:copy-of select="."/>
</xsl:template>

Case sensitive MySQL column

Make a case sensitive varchar column:

CREATE TABLE `page_dm` (
`url` varchar(500) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
http://dev.mysql.com/doc/refman/5.0/en/create-table.html

Different files for log4perl levels

log4perl.rootLogger=DEBUG,CONSOLE,ViewableLog,DebugLog,ErrorLog

###################################################################################
# console - what to watch
log4perl.appender.CONSOLE=Log::Log4perl::Appender::Screen
log4perl.appender.CONSOLE.layout=PatternLayout
log4perl.appender.CONSOLE.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.CONSOLE.Filter = ViewableFilter

  log4perl.filter.ViewableFilter        = sub {    \
       my %p = @_;                           \
       $p{log4p_level} eq "FATAL" or          \
       $p{log4p_level} eq "ERROR" or          \
       $p{log4p_level} eq "INFO" or          \
       $p{log4p_level} eq "WARN"           \
                                          }

###################################################################################
# Viewable log - record of CONSOLE
log4perl.appender.ViewableLog=Log::Log4perl::Appender::File
log4perl.appender.ViewableLog.layout=PatternLayout
log4perl.appender.ViewableLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.ViewableLog.filename = logs/output.log
log4perl.appender.ViewableLog.Filter = ViewableFilter

###################################################################################
# Error log - warnings and errors
log4perl.appender.ErrorLog=Log::Log4perl::Appender::File
log4perl.appender.ErrorLog.layout=PatternLayout
log4perl.appender.ErrorLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
log4perl.appender.ErrorLog.filename = logs/error.log
log4perl.appender.ErrorLog.Filter = ErrorFilter

  log4perl.filter.ErrorFilter        = sub {    \
       my %p = @_;                           \
       $p{log4p_level} eq "FATAL" or          \
       $p{log4p_level} eq "ERROR" or          \
       $p{log4p_level} eq "WARN"           \
                                          }

###################################################################################
# Debug Log - everything
 log4perl.appender.DebugLog = Log::Log4perl::Appender::File
 log4perl.appender.DebugLog.layout=PatternLayout
 log4perl.appender.DebugLog.layout.ConversionPattern=[%d] [%p %c] - %m%n
  log4perl.appender.DebugLog.filename = logs/debug.log
  log4perl.appender.DebugLog.Filter = AllFilter

  log4perl.filter.AllFilter        = sub {    \
       my %p = @_;                           \
       $p{log4p_level} eq "FATAL" or          \
       $p{log4p_level} eq "ERROR" or          \
       $p{log4p_level} eq "WARN" or          \
       $p{log4p_level} eq "INFO" or          \
       $p{log4p_level} eq "DEBUG" or          \
       $p{log4p_level} eq "TRACE"           \
                                          }

###################################################################################
# To enable DEBUG-level logging for a particular module (and any modules that subclass it),
# un-comment the following and change e.g. 'TempTopicsAdminTools.ModuleManager' to the your own module.

##log4perl.logger.TempTopicsAdminTools.ModuleManager=DEBUG
#log4perl.logger.TempTopicsAdminTools.PageManager=WARN
#log4perl.logger.TempTopicsAdminTools.CategoryManager=WARN

Remove MySQL user password

root@dsdsdsdsd:~# mysql -p
Enter password:
mysql> use mysql;
mysql> update user set Password='' where User='yourusername';
mysql> commit;
mysql> flush privileges;
mysql> quit;

Phone twiddles

Any phone:

  • *#06# - show IMEI number

Blackberry only:
  • from home screen: Hold Alt and type E, A, C, E - displays OS version

Elementary JSON

{
"Image": {
"Width":800,
"Height":600,
"Title":"View from 15th Floor",
"Thumbnail":
{
"Url":"http:\/\/scd.mm-b1.yimg.com\/image\/481989943",
"Height": 125,
"Width": "100"
},
"IDs":[ 116, 943, 234, 38793 ]
}
}

Thanks Yahoo!

View the swap file usage in linux

/sbin/swapon -s

Reasons not to use stored procedures in databases

http://www.tonymarston.net/php-mysql/stored-procedures-are-evil.html

Coloured log output

Tail the log and pipe it through this:

#!/usr/bin/perl

use warnings;
use strict;
use Term::ANSIColor qw(color);

while( <> ) {
chomp;
s/\t/ /g;
(/ERROR|failed/) && do {
print( color( 'red' ). $_ .color( 'reset' )."\n" );
next;
};
(/WARN/) && do {
print( color( 'magenta' ). $_ .color( 'reset' )."\n" );
next;
};
(/succeeded/) && do {
print( color( 'green' ). $_ .color( 'reset' )."\n" );
next;
};
(/INFO/) && do {
print( color( 'yellow' ). $_ .color( 'reset' )."\n" );
next;
};
(/DEBUG/) && do {
print( color( 'blue' ). $_ .color( 'reset' )."\n" );
next;
};
print $_."\n";
}

Taking Screenshots in Mac OS X

http://guides.macrumors.com/Taking_Screenshots_in_Mac_OS_X

Shortcuts

* Command-Shift-3: Take a screenshot of the screen, and save it as a file on the desktop
* Command-Shift-4, then select an area: Take a screenshot of an area and save it as a file on the desktop
* Command-Shift-4, then space, then click a window: Take a screenshot of a window and save it as a file on the desktop
* Command-Control-Shift-3: Take a screenshot of the screen, and save it to the clipboard
* Command-Control-Shift-4, then select an area: Take a screenshot of an area and save it to the clipboard
* Command-Control-Shift-4, then space, then click a window: Take a screenshot of a window and save it to the clipboard

In Leopard, the following keys can be held down while selecting an area (via Command-Shift-4 or Command-Control-Shift-4):

* Space, to lock the size of the selected region and instead move it when the mouse moves
* Shift, to resize only one edge of the selected region
* Option, to resize the selected region with its center as the anchor point

Can't connect to MySQL

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

Reason: mysqld is not running!

How to see the answers for free on Expert Exchange

http://www.experts-exchange.com

Solution:
Scroll down

Code folding in vi

All you ever wanted to know about code folding in vim, including keys: http://www.linux.com/archive/articles/114138

Config settings for code folding: http://smartic.us/2009/04/06/code-folding-in-vim/

Vim documentation for folding: http://www.vim.org/htmldoc/fold.html
There are six methods to select folds:

manual manually define folds
indent more indent means a higher fold level
expr specify an expression to define folds
syntax folds defined by syntax highlighting
diff folds for unchanged text
marker folds defined by markers in the text

Key concepts:
  • To use the indent method you need to set the :tabstop correctly
  • Syntax method requires the correct syntax files to be present
Commands:
  • zc -> close fold
  • zo -> open fold

How to talk to memcached

  1. telnet to the server (or localhost) on the right port
  2. type "flush_all" to invalidate the whole cache
  3. type "delete [key]" to invalidate a particular item
See also the memcache protocol

Combine multiple lines in multiple files into a single spreadsheet row

for k in $(ls *.xml); do echo "$(perl -e'print "$ARGV[0]\t"' $k)""$(head -14 $k | egrep 'h:shortdesc|dc:title' | perl -lne'($t)=$_=~m{([^<]+)} if ! $t; ($d)=$_=~m{([^<]+)<} if ! $d;END{print "$d\t$t"}')"; done

Toggle visibility of non-printable characters in Mac Word

Preferences | View | Nonprinting characters -> tick boxes

graphical perl debugger

Devel::ptkdb

requires Tk...which requires X11.

seq on Mac?

Mac doesn't have seq like Redhat does.

instead of: seq 1 10
seq [first] [increment] [last]

try: jot 10 1 10
jot [reps] [start] [finish] [step]

Pass in an extra parameter to perl -n

Use an environment variable

for k in $(cat list_of_ids); do export KK=$k; perl -F"\t" -lane'print if ($F[3] eq $ENV{KK})' data/master_list_of_queries >> new_data_file; done

How big are my MySQL databases?


SELECT TABLE_SCHEMA AS 'Database', TABLE_NAME AS 'Table', CONCAT(ROUND(((DATA_LENGTH + INDEX_LENGTH - DATA_FREE) / 1024 / 1024),2)," MB") AS Size FROM INFORMATION_SCHEMA.TABLES

Where you might find Apache files

  • /usr/sbin/apachectl
  • /usr/sbin/httpd
  • /etc/httpd/conf/httpd.conf
  • /var/log/httpd/error_log
  • /etc/httpd/
  • /etc/httpd/modules/

Combinations, permuations and iterations

To generate all combinations or permutations of a fixed list, use Math::Combinatorics

To generate sequential values for a set of slots, e.g. all binary numbers, or the number of 'max_results' for several modules do this:

  1. add one to the first slot
  2. if that takes it over the maximum, set it to zero and add one to the next slot
  3. repeat step 2 until you reach all zeroes
  4. if all zeroes, you are finished.

Upper and lowercase in vi

Select the text you want using visual mode, then type U for uppercase or u for lowercase.

Intermittent bugs

How do you investigate and fix a bug if you can't reproduce it?

Turn a lot of logging on, then check the logs for occurrences of the bug.

Setting up xemacs xslt-process mode

I set all these options in the environment:

#########################
# copied from /etc/java/java.conf
# JPackage Project
#########################
# Location of jar files on the system
export JAVA_LIBDIR=/usr/share/java
# Location of arch-specific jar files on the system
export JNI_LIBDIR=/usr/lib/java
# List of known java homes (used for autodetection if none is provided)
export JAVA_HOME_LIST=$JAVA_LIBDIR-utils/java_home.list
# Root of all JVM installations
export JVM_ROOT=/usr/lib/jvm
# Default jvm
export JAVA_HOME=$JVM_ROOT/java
# Options to pass to the java interpreter
export JAVACMD_OPTS=
#########################


export CLASSPATH=/usr/share/java

Now when I try to run xslt-process, it says:
Starting the BeanShell. Please wait...

...but then straight away it still always says:
Could not process file, most probably (Xalan1|Saxon) could not be found!

What I think is happening:
  • xalan-2.4.1.jar is installed, not xalan1 as is required.
  • Not all of saxon's dependencies are installed.

Installing an XSLT processor

xsltproc, Saxon or Xalan: http://www.sagehill.net/docbookxsl/InstallingAProcessor.html

Installing Saxon on Linux. Is JAXP 1.3 required? And then how would I test it anyway?

Could install Xalan. But it's already included with Java:
java org.apache.xalan.xslt.EnvironmentCheck

Why can't xemacs' xlst-process mode find any xslt processor?

Simple XSL test

xml.xml file:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<hello-world>
<greeter>An XSLT Programmer</greeter>
<greeting>Hello, World!</greeting>
</hello-world>

xsl.xsl file:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/hello-world">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1>
<xsl:value-of select="greeting"/>
</H1>
<xsl:apply-templates select="greeter"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="greeter">
<DIV>from <I><xsl:value-of select="."/></I></DIV>
</xsl:template>
</xsl:stylesheet>

Working with xemacs XSLT-process mode

M-x xslt-process-mode - enable xslt-process mode
C-c C-x v - run the xslt processor and view results (be sure to type slowly enough!)

M-x customize-group RET xslt-process - options menu: change engine, customise key bindings, etc.

NOTE: the default run command above may have problems under cygwin. Redefine it to C-x C-c C-v and it should work.

xemacs buffer control

C-x b [buffer] [enter] - select or create a named buffer
C-x C-b - list existing buffers
C-x 1 - close the buffer list

Emacs and Cygwin

Can't quit emacs from cygwin?

From within Cygwin, if you start xemacs with: xemacs -nw (for No Window), then C-x C-c to quit emacs does not work. Instead you must type C-g to exit.

xemacs mode line

How to interpret the status line in xemacs:
http://www.xemacs.org/Documentation/21.5/html/xemacs_4.html#SEC10

GNU info

navigate within info screens:














bgo to beginning of the page
?help
mchoose a menu item from the current page (has tab completion)
fchoose a cross-reference to follow (tab completion)
f?list all cross-references on the current page
lgo back to last page

Ctrl-gcancel menu command
isearch index for topic
ddirectory of all info pages
tgo to 'top' of current manual
ssearch forward
qquit info screen

Pass a parameter to XSL in Cocoon

In the sitemap:

<map:transform src="xslt/page.xsl">
<map:parameter name="param1" value="{1}"/>
</map:transform>

In the XSL:

<xsl:param name="param1"/>

...

<xsl:template match="whatever">
<xsl:attribute name="something">
<xsl:value-of select="$param1"/>
</xsl:attribute>
</xsl:template>

XSL variables

Set a variable
<xsl:variable name="something" select="21">

Use a variable
<xsl:value-of select="$something">

You can't change the value of variables.

Emacs

Emacs is desirable for its XSLT debug mode, Emacs::PDE, and font-lock-keywords mode

Viper is a full-featured Vi emulator for GNU Emacs and XEmacs. But if you don't use that, keep reading.

Emacs notes, from the perspective of a vi user

Problems:

* The manual calls for C-h (Ctrl-h) to be used as a special command
** but when using Putty from Windows, by default Ctrl-h just does a backspace.
** from Windows, it can't tell the difference between Ctrl-H and the backspace key
** This means if you re-map Ctrl-H, it also re-maps the Backspace key. I haven't solved this yet.

--------------------------------------------------------

To read the manual on key commands:

1) type F1, i - gets you to the info menu
2) type m, emacs, [enter] - takes you to the Emacs info file
3) Page down to "Fundamental Editing Commands", "Important Text-Changing Commands", etc. and press [enter] on the menu items you want (typing lowercase L takes you

'back' one page)

--------------------------------------------------------

Notes:

* Terminology: C-x means Ctrl-x, C-M-x means Ctrl-Meta-x - the Meta key is Alt under MS Windows)
* For some commands, holding Ctrl is required for the second character (e.g. quit: C-x, C-c), and for others commands it's not (e.g. undo: C-x u)
* Commands like this "M-x set-visited-file-name" mean: type Meta-x, then type the string 'set-visited-file-name'.
* After typing M-x you can also use tab-completion to find commands.

Translation of common Emacs commands for vi users:

commandviemacs

save file:wC-x C-s
save & exit read-only file:wq!C-x, C-c, follow prompts
save to a different file:w fooM-x set-visited-file-name
find a file to open
C-x C-f

delete to end of lineShift-dC-k

undouC-x u

uC-_ (hold Ctrl, press dash/hypen/underscore key)
redorbreak out of undo mode, and type C-_ again

note: these searches are case insensitive
search forward/C-s (incremental / search-as-you-type)

/C-s, [enter] (non incremental / type whole word, then search)
search backward?C-r (incremental)

?C-r, [enter] (non incremental)

note: even these *regex* searches are case insensitive. There is a way to make them case sensitive: set the variable `case-fold-search' to `nil'.
search forward using regex
C-M-s (incremental)
and backward
C-M-r


call out to the shell!M-! (Meta-Shift-1)
start a full subshell
M-x eshell


Notes on differences to vi:

* undo commands wrap around. Once you undo all your edits, the undo command reverses direction and starts re-doing the edits! break out of the undo mode and press C-_ (undo) again to change the direction of undo/redo command.

* files are autosaved to a seperate buffer. to recover after a crash, type: M-x recover-file foo.c


Emacs-only commands:

list commands in help menuF1, ?
get help on key combinationsF1, k, [some key combination]
toggle read-only status of the bufferC-x, C-q
get out of a commandC-g
redo an edit (undo the undo)type any harmless character to break out of undo mode. You will now be able to undo your undo commands.

remove help windowC-x 1
scroll the helpC-M-v

re-map a keyM-x global-set-key [enter]

XSL de-duping

example:

<xsl:choose> <xsl:when test="/session/dataset = 'news'"> <xsl:for-each-group select="item" by="lower-case(title)"> <xsl:apply-templates select="current-group()[1]"> </xsl:apply-templates></xsl:for-each-group> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="item[title != '']"> </xsl:apply-templates></xsl:otherwise>
</xsl:choose>

CSS basics

#id = id
.class = class

PHP 5 XML

SimpleXML
http://www.php.net/manual/en/ref.simplexml.php

$xml = simplexml_load_file($file);

$body = $xml->xpath("//body");

print $body->asXML();


PHP 4 XSL

XSLT extension (for PHP 5, use XSL)
http://www.php.net/manual/en/intro.xslt.php

NOTE:
This extension uses Sablotron and expat, which can both be found at http://www.gingerall.org/sablotron.html. Binaries are provided as well as source.

You must run configure with the --enable-xslt --with-xslt-sablot options.


<?php

$xml 
= <<<EOT
<?xml version="1.0"?>
<hello-world>
    <greeter>An XSLT Programmer</greeter>
    <greeting>Hello, World!</greeting>
</hello-world>
EOT;

$xsl = <<<EOT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/hello-world">
    <HTML>
      <HEAD>
        <TITLE></TITLE>
      </HEAD>
      <BODY>
        <H1>
          <xsl:value-of select="greeting"/>
        </H1>
        <xsl:apply-templates select="greeter"/>
      </BODY>
    </HTML>
  </xsl:template>
  <xsl:template match="greeter">
    <DIV>from <I><xsl:value-of select="."/></I></DIV>
  </xsl:template>
</xsl:stylesheet>
EOT;

$arguments = array(
     
'/_xml' => $xml,
     
'/_xsl' => $xsl
);

// Allocate a new XSLT processor
$xh xslt_create();

// Process the document
$result xslt_process($xh'arg:/_xml''arg:/_xsl'NULL$arguments);
if (
$result) {
    echo 
"SUCCESS, sample.xml was transformed by sample.xsl into the \$result";
    echo 
" variable, the \$result variable has the following contents\n<br />\n";
    
//echo "<pre>\n";
    
echo $result;
    
//echo "</pre>\n";
} else {
    echo 
"Sorry, sample.xml could not be transformed by sample.xsl into";
    echo 
"  the \$result variable the reason is that " xslt_error($xh);
    echo 
" and the error code is " xslt_errno($xh);
}
xslt_free($xh);

?>

PHP for Mac OSX

PHP arrays

This won't work:
php -r "$a = array( 'c' => array( 'b' => 1 ) );"

But this will:
php -r '$a = Array( "c" => Array( "b" => 1 ) );'

On Mac OSX

PHP command line

php -f file.php

file.php contains:
<?php
print "hello world";
?>

or a one-liner:

php -r "some code;"

Don't forget the trailing semicolon.

PHP 4 XML

DOM XML
http://www.php.net/manual/en/ref.domxml.php
(for PHP 5, use DOM)

Create a Document object from a file:

$doc = xmldocfile("myfile.xml");
if ($doc){
print $doc->dumpmem();
}


NOTE: PHP must be compiled with --with-dom and --with-xml.
phpinfo() will display this information right at the top.

The PHP 4.4.9 (Zend Engine) that comes with Mac OSX is not compiled --with-dom.

PHP 5 XSL


Introduction: The XSL extension implements the XSL standard, performing XSLT transformations using the libxslt library

Requirements: This extension uses libxslt which can be found at http://xmlsoft.org/XSLT/. libxslt version 1.0.18 or greater is required.

Installation: PHP 5 includes the XSL extension by default and can be enabled by adding the argument --with-xsl[=DIR] to your configure line. DIR is the libxslt installation directory.

// xsl document
$xsl = new DomDocument;
$xsl->load($xstemplate);

// xslt processor
$xp = new XsltProcessor();
$xp->importStylesheet($xsl);

// xml document
$xml_doc = new DomDocument;
$xml_doc->load($xmldata);

// perform the transform
$html = $xp->transformToXML($xml_doc);

PHP debug output

ob_start();
print_r( $xml_object );
$output = ob_get_clean();
$this->logger->debug('output=' . $output);

Zend PHP version

Zend Framework 1.5.1 requires PHP 5.1.4 

PHP regular expressions


/(.*)something/s

The s at the end causes the dot to match all characters including newlines.

Use a string to make a variable name

my $rank10 = 42;
{
    no strict 'refs';
    my $num = 10;
    print eval "\$rank$num";
}


result:
    42

Bash profile settings

~/.bash_profile gets called when you log in for the first time. It's your user-specific settings.

~/.bashrc gets called when you start a new shell. Only interactive shells and user scripts read this file.

Type a literal tab in vi

If you've got "convert tabs to spaces" turned on, type this to insert a real tab:
Ctrl-V [tab]

Enjoy logging with Zend

Output to the page within Zend PHP engine:

$writer = new Zend_Log_Writer_Stream('php://output');
$logger = new Zend_Log($writer);
$logger->log('Enjoy this test', Zend_Log::DEBUG);

Or to the webserver error log:

$writer = new Zend_Log_Writer_Stream('php://stderr');
$logger = new Zend_Log($writer);
$logger->debug('Beginning log');

Beware of backslashes in login strings

using URI to parse an ftp connection string like:
ftp://domain\user:pass@host/path
...can lead to problems.
The backslash is not a legal URI character, so $uri->user may bring back just the domain!

Scanning HTML

Screen scraping with HTML::TreeBuilder:

my $real_h1 = $tree->look_down(
    '_tag', 'h1',
    sub {
        my $link = $_[0]->look_down('_tag','a');
        return 1 unless $link; # no link means it's fine
        return 0 if $link->attr('href') =~ m{/dyna/}; # a link to there is bad
        return 1; # otherwise okay
    }
);

C# SQL database connections

One way to do it, building the SQL code by inserting parameters:

//get db connection to copy from
MySqlConnection sourceDbConn = getConnection(db);
sourceDbConn.Open();
try
{
System.Data.DataSet ds = new System.Data.DataSet();
MySqlDataAdapter da;
MySqlCommandBuilder cb;

da = new MySqlDataAdapter("SELECT id FROM page where pageType = '" + pageType + "'", sourceDbConn);
cb = new MySqlCommandBuilder(da);
ds.DataSetName = "pageIds";
da.Fill(ds);
foreach (DataTable thisTable in ds.Tables)
{
foreach (DataRow row in thisTable.Rows)
{
idsArray[i++] = Int32.Parse(row["id"].ToString());
}
}
return idsArray;
}
catch
{
throw new Exception("Failed to get list of page to publish");
}
finally
{
sourceDbConn.Close();
}
}


Another way to do it, with bound parameters:

// get feed changes - picking up all data required to create new feeds

MySqlCommand getFeeds = new MySqlCommand("select id, type, title, maxresults, minrelevance, mindate from feeds where client_id = ?client_id and updated_date > ?max_updated_date", editorialConn);
getFeeds.Parameters.AddWithValue("?client_id", selected_staging_client_id);
getFeeds.Parameters.AddWithValue("?max_updated_date", PublishChangesSince);
MySqlDataReader getFeedsRdr = getFeeds.ExecuteReader();

while (getFeedsRdr.Read())
{
Int32 FeedID = getFeedsRdr.GetInt32(0);
String FeedType = getFeedsRdr.GetString(1);
String FeedTitle = getFeedsRdr.GetString(2);
Int32 FeedMaxResults = getFeedsRdr.GetInt32(3);
float FeedMinRelevance = getFeedsRdr.GetFloat(4);
DateTime FeedMinDate = getFeedsRdr.GetDateTime(5);
}
getFeedsRdr.Close();
To get to the page denoted by auditd(8), type
man 8 auditd


iTunes graphic equalizer

The iTunes graphic equalizer is hidden in the 'Window' menu, on the Mac verison.

Native Perl configuration file

Define a configuration file as a Perl package, containing hash data:

$ cat data
package d;

$a = {
    1 => 2,
    b => 'c',
};

Use this method to read the data straight into Perl:

$ perl -MData::Dumper -le'eval { require "./data"; }; print Dumper($d::a)'
$VAR1 = {
          '1' => 2,
          'b' => 'c'
        };

This avoids the need to employ a parser, as the data is already in a Perl data structure format.

NOTE: You must specify the absolute path to the data file. I found that 'data' failed, where './data' succeeded.

If you leave out the package declaration in the data file, you can access the hash using $main::a

Perl OO

our @ISA = ('MyParent');

sub new {
        my $proto = shift;
        my $class = ref($proto) || $proto;
        my $self  = {};
        $self->{NAME}   = undef;
        $self->{AGE}    = undef;
        $self->{PEERS}  = [];
        bless ($self, $class);
        return $self;
}