<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UseStrict Consulting &#187; Perl</title>
	<atom:link href="http://usestrict.net/tag/perl-newbies/feed/" rel="self" type="application/rss+xml" />
	<link>http://usestrict.net</link>
	<description>Professional IT Solutions &#38; Training</description>
	<lastBuildDate>Fri, 10 Feb 2012 12:01:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Introduction to Ajax</title>
		<link>http://usestrict.net/2009/08/introduction-to-ajax/</link>
		<comments>http://usestrict.net/2009/08/introduction-to-ajax/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 21:56:08 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[how to]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=840</guid>
		<description><![CDATA[Introduction to Ajax, Ajax how-to]]></description>
			<content:encoded><![CDATA[<p>In this article, I provide an explanation of Ajax with a historical introduction. If you are eager to start seeing the code, please scroll down.</p>
<p>&nbsp;</p>
<h3>What’s Ajax?</h3>
<p>&nbsp;</p>
<p>Ajax stands for <em>Asynchronous Javascript And XML</em>. It’s a way to call back-end scripts asynchronously – that is, without impacting user experience/flow. Basically, you don&#8217;t even see the cursor become an hourglass or whatever other &#8220;waiting/processing&#8221; icon your system uses. It&#8217;s not a language, but a technique. As for back-end scripts, you can use whatever you feel more comfortable with: PHP, Perl, Java, JSP, Shell, C, etc. The way to choose which technology to use as back-end is not outside the scope of this article.</p>
<p>&nbsp;</p>
<h3>Historical approach for calling back-end apps</h3>
<p>&nbsp;</p>
<p>Throughout web-development history, the very first way used to achieve back-end processing followed by front-end display was to create a form and set the back-end script as the action to that form. Upon submission, the form fields would be sent to the back-end script as a series of special environment variables, which would then be handled by the programmed logic. The back-end output would be displayed on the screen (either the same page/frame or a different page/frame, depending on the target attribute of the form).</p>
<p>The catch 22 of this approach is that if you want to present another form after processing, that form must be produced by the back-end script, which leads to maintenance mayhem – to add or remove a field, you have to do so in both the original HTML and in the HTML of the back-end script.</p>
<p><span id="more-840"></span></p>
<p>&nbsp;</p>
<h3>Hidden IFRAMES and Javascript to the rescue</h3>
<p>&nbsp;</p>
<p>The natural evolution of the regular form submission was to avoid having to generate HTML from the back-end script. A technique that I eventually came up with (had never seen it before, but it was probably already out there) prior to adhering to Ajax was using a hidden IFRAME as target to a simple form containing an <em>action_cd</em> field and a <em>data</em> field. There would not be a regular submit button, but a set of input elements with <em>onclick</em> or <em>onchange</em> events and a regular (non-submit) button at the end. </p>
<p>In this approach, Javascript did all the work – when the user clicked the pseudo-submit button, an <em>onclick</em> event would read all the input fields and join them like a regular HTTP query (<code>field1=val1&#038;field2=val2</code>…). The <em>action_cd</em> value would be dynamically evaluated and the back-end script would receive the data string and action code and process it. Javascript would perform the submission when, say, a value of a drop-down field was selected, and the output would be a series of dynamically generated Javascript commands inside the IFRAME. Those commands would manipulate the user’s form (e.g. Auto-populate a &#8220;state&#8221; drop-down after selecting a &#8220;country&#8221; value). </p>
<p>Although this approach successfully handled the no-longer-need to submit and reload a form, it still had 2 main downsides: generating and maintaining Javascript code is not a simple task (especially due to having to escape quotes), and the whole procedure was still synchronous – you could see the hourglass, browser process bars, clicking sounds (IE), etc. It&#8217;s much better user experience, but still not the real deal, seamless/transparent back-end processing.</p>
<p>&nbsp;</p>
<h3>The XmlHttpRequest object</h3>
<p>&nbsp;</p>
<p>Javascript back-end calls are made possible thanks to the <em>XmlHttpRequest</em> object that most modern browsers now support. For IE 6 and older, it is done through an ActiveXObject. </p>
<p>&nbsp;</p>
<h3>Javascript code to initialize Ajax object</h3>
<p>&nbsp;</p>
<pre class="brush:javascript">

var xmlHttp; // global variable. It’s important for later on

function GetXmlHttpObject(){

      if (window.XMLHttpRequest){
        // code for IE7+, Firefox, Chrome, Opera, Safari
        return new XMLHttpRequest();
      }

      if (window.ActiveXObject){
        // code for IE6, IE5
        return new ActiveXObject("Microsoft.XMLHTTP");
      }
      return null;
}
</pre>
<p>It&#8217;s important to have a global variable in which to assign the XMLHttpRequest object, since this technique has its shortcomings when dealing with passing variables around. We&#8217;ll understand that better shortly. The function checks for the existence of <strong>window.XMLHttpRequest</strong> which is used in IE7 (finally, it complies to standards!), Firefox, and other non IE browsers, and checks for <strong>window.ActiveXObject</strong> existence for IE6 and 5. I’m not sure if this works on IE4 – it probably does not, but hopefully IE4 is already in extinction. If neither checks work, it returns null, which will be handled in the function calling the XMLHttpObject.</p>
<p>&nbsp;</p>
<h3>Making Synchronous Ajax calls (GET method)</h3>
<p>&nbsp;</p>
<p>Although the hype of Ajax is due to the &#8220;Asynchronosity&#8221; of the technique, it is also capable of making synchronous calls. Synchronous calls are important in cases where you don&#8217;t want to allow the user to do something while the back-end is checking a previous action, but also don&#8217;t want to have to submit the whole form.</p>
<pre class="brush:javascript">

function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // Synchronous call
      xmlHttp.open("GET",url,false); // "false" means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response
      // this function continues further down in the tutorial

}
</pre>
<p>Ajax calls can be done using GET or POST methods. I recommend GET methods for small queries, POST for large ones. There used to be a limit of 255 characters on URL fields – not sure if a) this is still true; b) this could apply to these Ajax techniques.</p>
<p>The call to the back-end is done by 2 commands: <strong>xmlHttp.open(Method,url,async)</strong>, and the <strong>xmlHttp.send(null)</strong> calls. For POST method, this is a little different, so we’ll stick to GET calls for the time being.</p>
<p>&nbsp;</p>
<h3>Handling back-end reply</h3>
<p>&nbsp;</p>
<p><em>Asynchronous Javascript And XML</em> isn&#8217;t the perfect name for Ajax. It should be more like Aja<strong>R</strong>, where R stands for Reply. The reason is because the reply can be either an XML structure or a plain text. We use <strong>xmlHttp.responseXML.documentElement</strong> if we’re handling XML, or a plain <strong>xmlHttp.responseText</strong> for plain text. Actually, we can use the latter for XML as well, especially when debugging the code (when you want to pop up the XML reply).</p>
<p>We use a try/catch block to capture any errors:</p>
<pre class="brush:javascript">
function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // Synchronous call

      xmlHttp.open("GET",url,false); // “false” means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response
      try {            

            alert("Ajax Response: n"+xmlHttp.responseText); // Just pop-up the reply
            return false;
      }
      catch(e) {
            alert(e); // if error, show it as a pop-up
            return false;
      }
}
</pre>
<p>&nbsp;</p>
<p>To handle the  reply as XML, you need to a) make sure your back-end script outputs an XML structure, and b), replace xmlHttp.reponseText for xmlHttp.responseXML.documentElement.</p>
<p>&nbsp;</p>
<pre class="brush:javascript">
// Just the try/catch block changed        

       try {
              data = xmlHttp.responseXML.documentElement;
        }
        catch(e) {
               alert(e);
               return false;
        }
</pre>
<p>The <code>data</code> variable now holds a DOM object of the XML structure. To access its elements, we use DOM functions. </p>
<p>Example XML structure:</p>
<pre class="brush:xml">
&lt;OUT&gt;
      &lt;STATUS&gt;Success&lt;/STATUS&gt;
      &lt;MSG type="some_type"&gt;This is a test message&lt;/MSG&gt;
&lt;/OUT&gt;
</pre>
<p>Accessing Example XML through DOM:</p>
<pre class="brush:javascript">

      // gets the Success text
      var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue;

      // Assign MSG object to msg variable
      var msg = data.getElementsByTagName(‘MSG’)[0]; 

      // gets the attribute “type”
      var msg_type = msg.getAttribute(‘type’); 

      // gets the text inside the MSG node
      var msg_text = msg.childNodes[0].nodeValue;
</pre>
<p>&nbsp;</p>
<h3>Putting it all together</h3>
<p>&nbsp;</p>
<pre class="brush:javascript">
function synch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”; 

      // Synchronous call
      xmlHttp.open("GET",url,false); // "false" means asynchronous = false
      xmlHttp.send(null);

      // the code above does the back-end call. Now we handle the response

      try {
            data = xmlHttp.responseXML.documentElement;
       }
       catch(e) {
             alert(e);
             return false;
       }

      // gets the Success text
      var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

      // Assign MSG object to msg variable
      var msg = data.getElementsByTagName(‘MSG’)[0]; 

      // gets the attribute “type”
      var msg_type = msg.getAttribute(‘type’); 

      // gets the text inside the MSG node
      var msg_text = msg.childNodes[0].nodeValue;
      alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);

      return true;
}
</pre>
<p>&nbsp;</p>
<h3>Making Asynchronous Ajax calls (GET method)</h3>
<p>&nbsp;</p>
<p>We saw on page 2 that what controls synchronicity of the Ajax call is the true/false value in the <code>open()</code> command. However, we also need changes in the way we handle the reply. We do that by setting <strong><em>onreadystatechange</em></strong> property on the xmlHttp object.</p>
<p> OnReadyStateChange should be a function that will check the <em><strong>readyState</strong></em> attribute of the xmlHttp object.</p>
<p>&nbsp;</p>
<h3>Understanding readyState</h3>
<p>&nbsp;</p>
<p>readyStates are the way Javascript controls what stage of the process the call is in. It ranges from 0 to 4, where 4 is the completed reply from the back-end script. We normally only care about readyState == 4. Here are the codes and meaning:</p>
<table>
<tr>
<td><strong>Value</strong></td>
<td><strong>State</strong></td>
</tr>
<tr>
<td>0</td>
<td>Uninitialized</td>
</tr>
<tr>
<td>1</td>
<td>Loading</td>
</tr>
<tr>
<td>2</td>
<td>Loaded</td>
</tr>
<tr>
<td>3</td>
<td>Interactive</td>
</tr>
<tr>
<td>4</td>
<td>Complete</td>
</tr>
</table>
<p>&nbsp;</p>
<h3>Setting onreadystatechange</h3>
<p>&nbsp;</p>
<p><code>onreadystatechange</code> can be assigned a anonymous <code>function() {  }</code> block, or a named function. Just be careful with function parameters – to this day, I have not been able to pass any parameters to the functions set to <code>onreadystatechange</code>. Hence the need for some global variables in play.</p>
<p>Let&#8217;s copy over our <code>sync_call()</code> function and make it <code>Async_call()</code></p>
<pre class="brush:javascript">
function Asynch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”;

      // onreadystatechange must be set BEFORE making the call

      // it takes the response handling code that we had in the sync_call() previously
      xmlHttp.onreadystatechange = function() {

            if (xmlHttp.readyState == 4) { // Complete

                  // Now we handle the response within the onreadystatechange
                  try {
                        data = xmlHttp.responseXML.documentElement;
                  }
                  catch(e) {
                        alert(e);
                        return false;
                  }

                  // gets the Success text
                  var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

                  // Assign MSG object to msg variable
                  var msg = data.getElementsByTagName(‘MSG’)[0]; 

                  // gets the attribute "type"
                  var msg_type = msg.getAttribute('type'); 

                  // gets the text inside the MSG node
                  var msg_text = msg.childNodes[0].nodeValue;

                  alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
                  return true;
            }

      }; // don’t forget the ';' at the end of the function() {} block!!

      // Asynchronous call
      xmlHttp.open("GET",url,true); // 'true' means asynchronous = true
      xmlHttp.send(null);
}
</pre>
<p>&nbsp;</p>
<p>As mentioned before, you can separate the anonymous function assignment into a named function. The good side of this is that your functions get more manageable, but the downside is that you might need global variables in order to share values between the main function and the <code>onreadystatechange,/code> function.</p>
<p>&nbsp;</p>
<pre class="brush:javascript">
function Asynch_call() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var url = “/url/to/your/backend/script?with=var1&#038;and=var2”; 

      // onreadystatechange must be set BEFORE making the call

      // it takes the response handling code that we had in the sync_call previously
      xmlHttp.onreadystatechange = handlerfunction; // See separate function below    

      // Asynchronous call
      xmlHttp.open("GET",url,true); // “true” means asynchronous = true
      xmlHttp.send(null);
}

function handlerfunction() {

      if (xmlHttp.readyState == 4) { // Complete – must be global xmlHttp variable

            // Now we handle the response within the onreadystatechange
            try {
                  data = xmlHttp.responseXML.documentElement;
            }
            catch(e) {
                  alert(e);
                  return false;
            }

             // gets the Success text
            var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

            // Assign MSG object to msg variable
            var msg = data.getElementsByTagName(‘MSG’)[0]; 

            // gets the attribute “type”
            var msg_type = msg.getAttribute(‘type’); 

            // gets the text inside the MSG node
            var msg_text = msg.childNodes[0].nodeValue;

            alert("Got the following back-end reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
            return true;

      }
}
</pre>
<p>&nbsp;</p>
<h3>Parsing forms to create the GET/POST strings</h3>
<p>&nbsp;</p>
<p>Since we are not submitting the form with the usual submit button, we have to handle building the queries ourselves. I came up with a function that mimics the way browsers handle function calls.</p>
<pre class="brush:javascript">
function build_post_string(frm) {

      var str;
      var poststr_array = [];

      if (!frm.id) {
            // assume it's a string. get the form object
            frm = document.getElementById(frm);
      }

      for (i=0;i&lt;frm.elements.length;i++){

            var elem = frm.elements[i];

            if (!elem.id) {
                  // skip any fields that don't have IDs
                  continue;
            }

            if (elem.type == 'radio' || elem.type == 'checkbox') {

                  // only grab radio buttons and checkboxes that are checked
                  if (!elem.checked) {
                        continue;
                  }

            }            

            // get select values
            if (elem.nodeName.match(/SELECT/i) &#038;&#038; elem.multiple) {

                  var sel_array = [];

                  for (var o=0;o&lt;elem.options.length;o++) {

                        if (elem.options[o].selected) {
                              sel_array[sel_array.length] = elem.id+"="+elem.options[o].value;
                        }

                  }

                  var sel_str = sel_array.join('&#038;');

                  // build key/value pairs for SELECTs
                  poststr_array[poststr_array.length] = sel_str;
            }
            else if (elem.nodeName.match(/SELECT/i)) {
                  poststr_array[poststr_array.length] = elem.id+'='+elem.options[elem.selectedIndex].value;
            }
            else {
                  // build key/value pairs for everything else
                  poststr_array[poststr_array.length] = elem.id+"="+elem.value;
            }

      }

      // build and return str
      str = poststr_array.join("&#038;");
      return str;
}
</pre>
<p>This function takes a given form by ID and iterates through all of its elements. It is important that all fields you want in the query have an ID attribute. Otherwise they will be skipped. <strong>The return from this function can be used for both GET and POST requests.</strong></p>
<p>&nbsp;</p>
<h3>Using POST method for Ajax calls</h3>
<p>&nbsp;</p>
<p>So far we saw that making GET calls is pretty straight-forward. POST calls are different in the way that they are not put in the HTTP Header, but rather in a separate packet. In order to do that, we need to set a few header variables:</p>
<pre class="brush:javascript">
function Asynch_call_with_post() {

      // initialize Ajax object
      var xmlHttp = GetXmlHttpObject(); 

      // Set the URL to your backend script with query vars
      var post_str = build_post_string(‘my_form’); 

      var url = “/url/to/your/backend/script?” + post_str;

      // onreadystatechange must be set BEFORE making the call
      // it takes the response handling code that we had in the sync_call previously
      xmlHttp.onreadystatechange = function() {

            if (xmlHttp.readyState == 4) { // Complete

                   // Now we handle the response within the onreadystatechange
                   try {
                         data = xmlHttp.responseXML.documentElement;
                    }
                    catch(e) {
                         alert(e);
                         return false;
                    }

                     // gets the Success text
                     var msg_status = data.getElementsByTagName(‘STATUS’)[0].childNodes[0].nodeValue; 

                      // Assign MSG object to msg variable
                     var msg = data.getElementsByTagName(‘MSG’)[0]; 

                     // gets the attribute “type”
                     var msg_type = msg.getAttribute(‘type’); 

                     // gets the text inside the MSG node
                     var msg_text = msg.childNodes[0].nodeValue;
                     alert("Got the following backend reply: " + msg_status + "n" + msg + "n" + msg_type + "n" + msg_text);
                     return true;
               }

        }; // don't forget the ';' at the end of the function() {} block

        // Asynchronous call
        xmlHttp.open('POST',url, true); // Replace "GET" with "POST"

        // Set headers
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.setRequestHeader("Content-length", url.length);
        xmlHttp.setRequestHeader("Connection", "close");

        // Send the packet. Note that it’s no longer null as parameter to send
        xmlHttp.send(url);
}
</pre>
<p>&nbsp;</p>
<h3>Showing/Hiding "Processing…" messages</h3>
<p>&nbsp;</p>
<p>Since Ajax in Asynchronous mode is 100% transparent to the user, it is necessary to handle our own messages asking the user to wait until processing finishes. The simplest way to do this is by using a <code>DIV</code> element with initial display property set as none, or visibility set as hidden (the difference is that <code>visibility="hidden"</code> makes the element still occupy its space in the page, whereas <code>display="none"</code> effectively removes the element from the page and the space that it occupied).</p>
<p>Typically, I include code to show the element in the Ajax function, and code to hide it again in the <em>onreadystatechange</em> function (where readyState == 4). </p>
<pre class="brush:javascript">
        document.getElementById(‘wait_image’).display = ‘block’;
        document.getElementById(‘wait_image’).display = ‘none’;
</pre>
<p>&nbsp;</p>
<h3>Third-Party AJAX Libraries</h3>
<p>&nbsp;</p>
<p>There are several Ajax in a box libraries out there, but I am not comfortable with using them for company applications. The reason being is that Ajax is very powerful and can very well make calls to the maintainer's website to steal/capture sensitive information.  </p>
<p>Google provides Java code that generates Ajax during build – that is a typical example of us not being able to control Ajax code generated. </p>
<p>&nbsp;</p>
<h3>Testing the back-end script</h3>
<p>&nbsp;</p>
<p>There are 2 simple ways of testing the back-end script. With PHP, you can access both GET and POST variables through the <code>$_REQUEST</code> array. Perl CGI doesn’t really care if it’s GET or POST. I don’t know how JSP can handle it. With this being said, I simply have the Ajax alert the URL variable and return false. I then copy the URL variable and paste it in another window to see the output.</p>
<p>I strongly recommend debugging with Firefox – it has a handy error console and also parses the output XML or complains if it’s not built right.</p>
<p>&nbsp;</p>
<h3>Keeping IE from crashing with the XMLs</h3>
<p>&nbsp;</p>
<p>I'm pretty sure that Microsoft IE developers have some satisfaction in making web developers go crazy. That's how I felt when I started working with XML and Ajax, and although my app was working fine in Firefox, it kept crashing bad in IE. After some googling, I found out that I needed to set some headers in order to keep IE from blowing up. I already had the <code>"Content-type: text/xml"</code> header in place, but it appears that IE needs some caching control and expiry headers as well.</p>
<p>This is what I use in PHP:</p>
<pre class="brush:php">
        header("Expires: Fri, 09 Jan 1981 05:00:00 GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", FALSE); // FALSE means add this Cache-Control line instead of replacing the previous one
        header("Pragma: no-cache");
        header("Content-type: text/xml");
</pre>
<p>In Perl, setting headers is simple: just <code>print</code> them before printing any content. When you're done printing all your headers, print an empty newline to indicate where the page content will go.</p>
<p>I hope you've enjoyed this tutorial. Feel free to paste comments regarding your experience and preferences.</p>
<p>&nbsp;</p>
<h3>Book Suggestions:</h3>
<p>&nbsp;</p>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=14&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script><br />
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/08/introduction-to-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl: Installing DBD::Oracle + Oracle Instant Client on Ubuntu 9.04</title>
		<link>http://usestrict.net/2009/07/perl-installing-dbdoracle-on-ubuntu-904-and-oracle-instant-client/</link>
		<comments>http://usestrict.net/2009/07/perl-installing-dbdoracle-on-ubuntu-904-and-oracle-instant-client/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 16:17:20 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Accept]]></category>
		<category><![CDATA[article material]]></category>
		<category><![CDATA[course]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[dbd]]></category>
		<category><![CDATA[dbd::oracle]]></category>
		<category><![CDATA[dbi]]></category>
		<category><![CDATA[distro]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[dpkg]]></category>
		<category><![CDATA[everything]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[gazillion times]]></category>
		<category><![CDATA[home directory]]></category>
		<category><![CDATA[Install]]></category>
		<category><![CDATA[Instant]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[LIBRARY]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[nbsp]]></category>
		<category><![CDATA[oracle db]]></category>
		<category><![CDATA[oracle distribution]]></category>
		<category><![CDATA[Oracle Instant Client]]></category>
		<category><![CDATA[perl 5]]></category>
		<category><![CDATA[perl mcpan]]></category>
		<category><![CDATA[pre requisites]]></category>
		<category><![CDATA[root]]></category>
		<category><![CDATA[root password]]></category>
		<category><![CDATA[rpm]]></category>
		<category><![CDATA[Set]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[Site]]></category>
		<category><![CDATA[sudo]]></category>
		<category><![CDATA[surprise]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[using oracle]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<category><![CDATA[Windows XP]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=789</guid>
		<description><![CDATA[Easy to follow steps on how to install DBD::Oracle using Oracle Instant Client on Ubuntu 9.04]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I finally got a new laptop at work &#8211; which meant of course that I had to reinstall everything. Although we use Windows XP, there&#8217;s one app that I have to run through Linux. The solution was <a href="http://www.virtualbox.org/" target="_blank">Sun&#8217;s VirtualBox</a> running <a href="http://www.ubuntu.com/" target="_blank">Ubuntu 9.04</a>. When I tried to run the app, I realized that I still needed to install DBI and DBD::Oracle &#8211; which brings me to this article. Nothing better than a reinstall to generate article material <img src='http://usestrict.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>DBD::Oracle is usually a pain to install if you haven&#8217;t already done it a gazillion times. After that, it&#8217;s just an annoying itch. In this article I&#8217;ll cover installing DBD::Oracle using Oracle Instant Client, Ubuntu 9.04, and Perl 5.10. Since we&#8217;re using the Instant Client, you&#8217;ll need some Oracle DB you can connect to in order to do the testing. You can choose to skip testing altogether, but you might be into a surprise later.<span id="more-789"></span></p>
<p>&nbsp;</p>
<h2>DBI and DBD::Oracle</h2>
<p>Installing the <strong>DBI</strong> is always easy &#8211; regardless if you&#8217;re running Windows or Linux. Just follow the steps.</p>
<ol>
<li>Get root password if you don&#8217;t already have one: <code><strong><em>sudo passwd root</em></strong></code></li>
<li>Switch to root: <code><strong><em>su -</em></strong></code></li>
<li>Run CPAN: <code><em>perl -MCPAN -e shell</em></code></li>
<li>Check if DBI is already installed: <code><strong><em>m DBI</em></strong></code></li>
<li>If it&#8217;s not installed, install it: <code><strong><em>install DBI</em></strong></code></li>
</ol>
<p>That should do the trick for the DBI. The DBD::Oracle is a bit more complicated and we&#8217;ll just use CPAN to download it for us. The rest is manual.</p>
<ol>
<li>Check for DBD::Oracle: <code><strong><em>m DBD::Oracle</em></strong></code></li>
<li>Download it: <code><strong><em>get DBD::Oracle</em></strong></code></li>
<li>Exit CPAN: <code><strong><em>q</em></strong></code></li>
</ol>
<p>Now we should have the DBD::Oracle distribution downloaded to our CPAN build directory. If you don&#8217;t know where to find it, look for <code>.cpan</code> dir under your root home or (if you started CPAN for the first time doing <code>sudo</code> from your main user, look for it under your main user&#8217;s home directory). We&#8217;ll leave that distro aside for a moment and work on the other pre-requisites.</p>
<p>&nbsp;</p>
<h2>Oracle Instant Client</h2>
<p>Download the instant client packages you&#8217;ll need. I chose to download the RPMs and convert them to .deb files using <code>alien</code>. Oracle also provides .zip files if you don&#8217;t want to do it the <code>alien</code> way.</p>
<p><a href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html" target="_blank">Oracle Instant Client Download Site i386</a><br />
<a href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linux-amd64.html" target="_blank">Oracle Instant Client Download Site AMD64 32- and 64-bit</a></p>
<p>Accept the license agreement by clicking the Accept radio button. Since the i386 and amd64 files have different names, check the bold words in the file names to know which ones to download (the names below are for the i386 platform). Also, if you don&#8217;t have a user_id for Oracle, you&#8217;ll be prompted to register one once you click the link. It&#8217;s free of charge.</p>
<ul>
<li>oracle-instantclient11.1-<strong>basic</strong>-xx.x.x.x.x-x.i386.rpm</li>
<li>oracle-instantclient11.1-<strong>sqlplus</strong>-xx.x.x.x.x-x.i386.rpm</li>
<li>oracle-instantclient11.1-<strong>devel</strong>-xx.x.x.x.x-x.i386.rpm</li>
</ul>
<p>AMD64 has only zip files from what I could find, and they&#8217;re named a bit differently, too (remove the <span style="color: red;">32</span> for the 64-bit version:</p>
<ul>
<li>instantclient-<strong>basic</strong>-linuxAMD64-<span style="color: red;">32</span>-xx.x.x.x.x-yyyymmdd.zip</li>
<li>instantclient-<strong>sqlplus</strong>-linuxAMD64-<span style="color: red;">32</span>-xx.x.x.x.x-yyyymmdd.zip</li>
<li>instantclient-<strong>sdk</strong>-linuxAMD64-<span style="color: red;">32</span>-xx.x.x.x.x-yyyymmdd.zip</li>
</ul>
<p><em>Note: Extract the zips into a directory called instantclient and skip to the <strong>Set Up your Environment Variables</strong> section if you&#8217;re using the AMD64 or i386 zip files.</em></p>
<h2>Install alien and libaio</h2>
<p>Now is the time to install <code>alien</code>, which is an application that converts rpm files into .deb format to be used with <code>dpkg</code>. Instant Client also requires <code>libaio</code>. Both can be installed through the Synaptic Package Manager. Just open it, look for <code>alien</code>, mark it for install and do the same for <code>libaio</code> and <code>libaio-dev</code>. Once they&#8217;re installed, you&#8217;re good to move on to install the Instant Client. Just don&#8217;t forget to exit Synaptic Package Manager, since we&#8217;ll be using <code>dpkg</code> and it won&#8217;t work if Synaptic is open.</p>
<p>&nbsp;</p>
<h2>Install Oracle Instant Client</h2>
<p>First step to install Oracle Instant Client from rpm files is to convert them into .deb files. Do that with <code>alien</code> by running the following command (from a command line in the directory where you downloaded your RPMs):</p>
<p><code>$ sudo alien --scripts *.rpm</code></p>
<p>It takes a little while to run, so be patient. Once it&#8217;s complete, install the newly created .deb files:</p>
<p><code>$ dpkg -i *.deb</code></p>
<p>&nbsp;</p>
<h2>Set up your Environment Variables</h2>
<p>The nasty thing about rpm files is that it&#8217;s not always easy to know where the files were installed. If you opted for the zip file approach, your install will most definitely be different. For RPM install, add this to your <code>.bashrc</code> file (swap xx.x for your oracle version):</p>
<p><code><br />
export ORACLE_HOME=/usr/lib/oracle/xx.x/client<br />
export PATH=$PATH:$ORACLE_HOME/bin<br />
export LD_LIBRARY_PATH=$ORACLE_HOME/lib<br />
</code></p>
<p><strong>Update:</strong> If you get an ELFCLASS64 error, try setting LD_LIBRARY_PATH to $ORACLE_HOME/lib32 instead.</p>
<p>Reload your <code>.bashrc</code> file:<br />
<code>$. ~/.bashrc</code></p>
<p>Note: by default, Oracle Instant Client doesn&#8217;t come with a <code>tnsnames.ora</code> file or the directory structure where it&#8217;s usually found. We&#8217;ll have to create that ourselves -</p>
<p><code>$ mkdir -p $ORACLE_HOME/network/admin; touch $ORACLE_HOME/network/admin/tnsnames.ora</code></p>
<p>&nbsp;</p>
<h2>Install DBD::Oracle</h2>
<p>It&#8217;s time to finally install DBD::Oracle. Go to your CPAN build directory and <code>cd</code> into <code>DBD-Oracle-*</code>. As a user having the environment variable set from the previous section, run Makefile.PL portion.</p>
<p><code>$ perl Makefile.PL</code></p>
<p>There&#8217;s no need to set INC or LIB with the <code>alien</code> approach, but if you run into any issues, try giving Makefile.PL the path to your include dir for INC, and lib dir for LIB.</p>
<p>Next, run</p>
<p><code>$ make</code>.</p>
<p>It will raise a few warnings, but unless it exits with an error, you should be OK.</p>
<p>The next logical step is to run make test. However, this will undoubtedly fail unless you have a valid entry in your tnsnames.ora file. If you don&#8217;t, you can skip this test and hope that everything works later on. Otherwise, update your <strong>tnsnames.ora</strong> file with a valid entry, and set one more environment variable before running the test:</p>
<p><code>$ export ORACLE_USERID="user/passwd@tns_entry_name"</code><br />
<code>$ make test</code></p>
<p>This is usually the hardest part to pass with total success. Many things can go wrong. In my case, the valid entry I use doesn&#8217;t have full grants to the user I log in as. This always triggers an error on the create/access sequences portion of the testing. I simply ignore it nowadays &#8211; make sure you analyze your test results thoroughly before choosing to ignore the errors as well.</p>
<p>Now that the testing is over, simply run<br />
<code>$ make install</code><br />
as a super user and you&#8217;re all set!</p>
<p>&nbsp;</p>
<h3>Book suggestions:</h3>
<div style="text-align: center;"><script type="text/javascript">// <![CDATA[
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=11&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
// ]]&gt;</script></div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/07/perl-installing-dbdoracle-on-ubuntu-904-and-oracle-instant-client/feed/</wfw:commentRss>
		<slash:comments>67</slash:comments>
		</item>
		<item>
		<title>Recursion with Perl and CDS</title>
		<link>http://usestrict.net/2009/06/recursion-with-perl-and-cds/</link>
		<comments>http://usestrict.net/2009/06/recursion-with-perl-and-cds/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 22:16:10 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[CDS]]></category>
		<category><![CDATA[complex data structures]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[subroutine]]></category>
		<category><![CDATA[trim]]></category>
		<category><![CDATA[trimming]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=720</guid>
		<description><![CDATA[Recursion on Perl Complex Data Structures made easy.]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>: Changed subroutine to comply with <a href="http://www.amazon.com/gp/product/0596001738?ie=UTF8&#038;tag=usst-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0596001738" target="_blank">Perl Best Practices</a><img src="http://www.assoc-amazon.com/e/ir?t=usst-20&#038;l=as2&#038;o=1&#038;a=0596001738" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
<p><strong>Update2</strong>: Removed the prototype from the subroutine.</p>
<p>I&#8217;ve always had a problem with recursion. Not with the general theory that a function will call itself, etc &#8211; no, that&#8217;s easy. The hard part was when I had to deal with complex data structures in Perl (an array- or hashref containing a hash of arrays of hashes, a gazillion levels deep). Well, I guess anyone would have a hard time with that kind of data.</p>
<p>Anyway, in this post I don&#8217;t intend to get all complicated explaining all the kinds of recursions out there. If you want that, check <a href="http://en.wikipedia.org/wiki/Recursion_(computer_science)" target="_blank">this article at wikipedia</a>. What I do want to do is help all of those who are in the situation I was in, by explaining in the simplest way possible how to deal with this scenario.<span id="more-720"></span></p>
<p>Let&#8217;s start with a need. I have a complex data structure that needs its spaces trimmed on both sides. But since I&#8217;m lazy, I&#8217;d like my subroutine to modify the data directly, and not return the modified value (pass by reference, not pass by value). </p>
<p>Here&#8217;s our data structure:</p>
<p>&nbsp;</p>
<pre class="brush:perl">
    my $data = [
                       {
                          key1 => '   trim me!   ',
                          key2 => '   trim me too!    ',
                       },
                       [
                          'some element to trim   ',
                          '    another one    ',
                       ],
                       '    a simple string needing trimming    ',
                  ];
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><code>$data explained</code>:  an array containing 3 elements: element 0 is a hashref of keys <code>"key1"</code> and <code>"key2"</code>, element 1 is an arrayref of 2 elements. Element 3 is a simple string. All values have some extra spaces that need trimming (or so they say). We could use whatever number of levels and data types we want (except for anonymous subroutines, I guess &#8211; let&#8217;s not get too complicated).</p>
<p>Now, to trim all that, I want to be able to simply call <code>trim()</code> à la PHP. </p>
<p>&nbsp;</p>
<pre class="brush:perl">
     trim($data); # note the lack of the lvalue (lvalue = rvalue)
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>I also want it to accept simple arrays and hashes, and the references thereof: <code>trim(@array); trim(@array); trim(%hash); trim(%hash); trim($string)</code>. After all, I never know what kind of data my colleagues will be working with. Better have it deal with everything.</p>
<p>The logic to do that is this:  our subroutine will have to do the trimming (s///g) on scalars only. For that, it has to check if the data it received is a hash, array, etc, and if it is, iterate through each element and trim the value&#8230; but only if the element is not itself a hash, array, etc. Found it confusing? No problem, it really is.</p>
<p>In Perl, if I tried to remove the white space from element 0 of my <code>$data</code>  variable, it wouldn&#8217;t work. The reason being is that if I printed <code>$data->[0]</code> onto the screen, I&#8217;d get a funny looking output, something like <code>HASH(0x1004f5f0)</code>. That&#8217;s Perl&#8217;s way of saying that you have a HASH structure stored in memory position 0x1004f5f0. You can try to trim the spaces off of that string, but it won&#8217;t do you any good. The elements of your hash will still be untouched. That&#8217;s why you need to <em>de-reference</em> your data structures and dive into them.</p>
<p>To de-reference a structure is simple, just add a % in front of the variable if it&#8217;s a hashref, or an @ if it&#8217;s an array. But how do you know which is which? Use <code>ref()</code>.</p>
<p>&nbsp;</p>
<pre class="brush:perl">
       print ref($data->[0]) . "n"; # HASH
       print ref($data->[1]) . "n"; # ARRAY
       print ref($data->[3]) . "n"; # empty string, which is false
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><code>ref()</code> tells you what kind of data you are dealing with. It returns <code>CODE</code> if you have a closure or anonymous subroutine, but we&#8217;re not going there today.</p>
<p>So, now that we know how to identify the type of element we&#8217;re going to be working with, we can build our subroutine&#8230;</p>
<p>&nbsp;</p>
<pre class="brush:perl">
sub trim() {
	for my $param (@_) {
		if (ref($param) eq 'ARRAY') {
			for my $element (@{$param}) {
				trim($element);
			}
		}
		elsif (ref($param) eq 'HASH') {
			for my $val (values %{$param}) {
				trim($val);
			}
		}
		elsif (ref($param) eq 'CODE') {
			return;
		}
		else {
			$param =~ s/(^s+|s+$)//g;
		}
	}
}
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><code>trim()</code> explained:</p>
<p>We&#8217;re working with passing elements by reference instead of by value. This means that the elements themselves will be modified &#8211; no need to return any data. The first thing we do is to iterate through all parameters passed to <code>trim()</code>. In a subroutine, parameters (in our case, variables) are populated into the special <code>@_</code> array, allowing us to call <code>trim($var1, $var2, $var3)</code>  if we want.</p>
<p>We iterate through all elements of <code>@_</code> and verify if they are an Array. If they are, we iterate through each of their elements once, and call <code>trim()</code> again against them. That will handle as many nested arrays we want (or that your computer can handle). Now we have to make it deal with hashes. Same technique &#8211; use <code>ref()</code>  to see if it&#8217;s a hash. If it is, then iterate through each of its key/pair elements. There are several ways to do that. I personally prefer calling <code>keys</code>  to get the keys and use them to fetch the values of the hash. The value of the hash is passed to <code>trim()</code> for more validation. We also check to see if we received a <code>sub { }</code> (anonymous subroutine). In that case, we do nothing, just return.</p>
<p>Finally, after handling Arrays, Hashes and Anonymous subroutines, we can set up the actual trimming of the strings. We take the <code>$_[$i]</code> which is the parameter passed and remove the leading and trailing spaces with one neat substitution: <code>^s+</code> stands for leading spaces, <code>s+$</code> stands for trailing spaces, and it&#8217;s all joined by the <code>(  |  )</code> (this or that). We only call it once because we&#8217;re using the global (g) modifier of the substitution <code>s///g</code>.</p>
<p>And that&#8217;s all there is to it!</p>
<p><em>A note on prototypes:</em> This post generated a healthy discussion on prototypes. I had originally added the dollar prototype to the <code>trim()</code> subroutine, but that was forcing it to accept only scalars (strings and references), and not working with normal hashes and arrays. Thanks to everyone who participated in the discussion.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/06/recursion-with-perl-and-cds/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Perl and MQSeries for the faint of heart</title>
		<link>http://usestrict.net/2009/05/perl-and-mqseries-for-the-faint-of-heart/</link>
		<comments>http://usestrict.net/2009/05/perl-and-mqseries-for-the-faint-of-heart/#comments</comments>
		<pubDate>Fri, 29 May 2009 02:54:31 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[MQseries]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=502</guid>
		<description><![CDATA[Simple module for MQSeries communication using Perl]]></description>
			<content:encoded><![CDATA[<p>Today I managed to finally get Perl to put and get messages to MQ Series. It&#8217;s something that I&#8217;ve been wanting to do for quite some time, but didn&#8217;t have the time or even MQ knowledge to do so. </p>
<p>This post is intended for those who, like me, aren&#8217;t MQSeries gurus and can&#8217;t make much of the documentation of the MQSeries module in CPAN. I hope it serves you well. <span id="more-502"></span></p>
<h3>Very VERY Brief introduction to MQSeries</h3>
<p>MQ Series (recently renamed Websphere MQ) is a messaging software developed by IBM. There is a client and a server piece to it.</p>
<p>MQ Messages are transmitted between servers by means of <strong>queues</strong>. These queues are managed by <strong>Queue Managers</strong>. Queues can be configured to receive messages (input or request) and/or return messages (output or reply).</p>
<p>The installation of MQ series is beyond the scope of this post, but it&#8217;s important to know that if you need to communicate with a queue manager installed in a local machine, you have to use one set of APIs (the server APIs), and if you want to talk to a remote queue manager, you&#8217;ll use the client APIs. This is important for later on.</p>
<p>A MQ message is composed of 2 main parts: the <strong>MQ Message Descriptor (MQMD)</strong> and the <strong>Data</strong> portion. The MQMD portion works as a header where several fields can be set to tell the server how to handle the message. The fields we will be using in this tutorial are <strong>MsgId, CorrelId, MsgType, Expiry, ReplyToQ, and ReplyToQMgr</strong>. </p>
<p><strong>MsgId</strong>: Each message being sent into the server gets a unique Message ID. They never repeat, even when the server is restarted.</p>
<p><strong>CorrelId</strong>: The Correlation Id is how a reply message can be associated to a request message.</p>
<p><strong>MsgType</strong>: The kind of data you will be sending through the queues. We will be using a simple string format.</p>
<p><strong>Expiry</strong>: The amount of time that the server should keep the message in a queue.</p>
<p><strong>ReplyToQMgr</strong>: The name of the Queue Manager where the reply must be sent to.</p>
<p><strong>ReplyToQ</strong>: The name of the queue where the reply must be sent to.</p>
<p>You will find more information about the fields and MQ Series in general at the <a href="http://publib.boulder.ibm.com/iseries/v5r2/ic2924/books/csqzak05.pdf" target="_blank">MQSeries Application Programming Reference</a>. I couldn&#8217;t find a link to the hardcopy at Amazon, but you can consider getting <a href="http://www.amazon.com/gp/product/0738427624?ie=UTF8&#038;tag=usst-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0738427624">this one.</a><img src="http://www.assoc-amazon.com/e/ir?t=usst-20&#038;l=as2&#038;o=1&#038;a=0738427624" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
<p>Before trying to put or get messages, you will probably need to set the MQSERVER environment variable (for both Unix and Windows &#8211; don&#8217;t know how Mac works), since the client usually requires it. The value for MQSERVER is &#8220;CHANNEL_NAME/TCP/HOST_IP(PORT)&#8221;. There can be variances according to the settings of the host you&#8217;ll connect to, but this is the most common scenario.</p>
<p>[ad#middle_end]</p>
<h3>MQSeries CPAN modules</h3>
<p>CPAN has a very handy set of modules which allow us to communicate with MQSeries. The main module, MQSeries, exports all the funny named subroutines that you need to use to send and receive messages. If you don&#8217;t have working knowledge with C/C++ using MQ Series, then don&#8217;t even bother trying to use it. The Object Oriented modules (by the same author) are much simpler for the unseasoned MQ Series explorer (like myself).</p>
<p>First off, you will need to install the modules in your computer. If you&#8217;re working on windows, <a href="http://usestrict.net/2009/05/perl-and-mqseries-for-the-faint-of-heart/2009/01/15/perl-installing-mqseries-module-on-windows-xp/" target="_blank">read this article</a> to get it done. It&#8217;s simpler on Unix, but both cases require that you have the MQ Series client installed. You can get it from <a href="http://www-01.ibm.com/support/docview.wss?rs=171&#038;uid=swg24009961&#038;loc=en_US&#038;cs=utf-8" target="_blank">here</a></p>
<p>When you install MQSeries module from CPAN, you also get MQSeries::QueueManager, MQSeries::Queue, MQSeries::Message and some other goodies. If you didn&#8217;t get any of those automatically, make sure you install them before you go on.</p>
<h3>Writing your own MQSeries module</h3>
<p>Here we&#8217;ll write a few methods which should make people&#8217;s lives easier when communicating with MQ Series. Now, depending on the way your application works, you will probably have to handle the creating and breaking up of the Data portion of the message, but again, that&#8217;s outside the scope of this post.</p>
<p>So let&#8217;s get started&#8230;</p>
<p>Start your module by giving it a package name. Remember to end the code with a true value. We&#8217;ll also import the modules we&#8217;ll need</p>
<pre class="brush:perl">
package myMQModule;

use strict;
use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Queue;
use MQSeries::Message;

1; # end with a true value
</pre>
<p>Now let&#8217;s lay out the basics of our module.</p>
<pre class="brush:perl">
package myMQModule;

use strict;
use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Queue;
use MQSeries::Message;

sub new() { # our constructor
}

sub openQueueMgr() { # open the Queue Manager
}

sub openQueue() { # opens the Queue
}

sub putRequest() { # puts the message
}

sub getReply() { # gets the reply using the correlId
} 

1; # end with a true value
</pre>
<p>You&#8217;ll probably notice that we haven&#8217;t added methods to close the queue and the queue manager. That&#8217;s ok, since the MQSeries* modules do that for us.</p>
<p>[ad#middle_end]</p>
<p>Let&#8217;s go on with our methods. Starting with <tt>new()</tt>. We&#8217;ll use the basic instantiation code. You will probably need to enhance this to suit your own needs, such as calling <tt>openQueueMgr()</tt> and <tt>openQueue()</tt> automatically. For now, we&#8217;ll <a href="http://en.wikipedia.org/wiki/KISS_principle" target="_blank">KISS</a>.</p>
<pre class="brush:perl">
package myMQModule;

use strict;
use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Queue;
use MQSeries::Message;
use Carp; # exports carp, confess, etc.

sub new() { # our constructor
    my $invocant = shift;
    my $class = ref($invocant) || $invocant; # Object or class name
    my $self = {};       # initiate our handy hashref
    bless($self,$class); # make it usable
    return $self;
}

sub openQueueMgr() { # open the Queue Manager
}

sub openQueue() { # opens the Queue
}

sub putRequest() { # puts the message
}

sub getReply() { # gets the reply using the correlId
} 

1; # end with a true value
</pre>
<p>Now we need to get the Queue Manager and the Queue open. In real life, you&#8217;ll probably have several queue managers and several queues. In our example, we&#8217;ll use 2 of each, one pair for outgoing traffic and another for incoming. Remember that this depends on your MQ Series configuration. These examples should simply allow you to get your toes wet in preparation before diving into your custom settings. </p>
<pre class="brush:perl">
...
sub openQueueMgr() { # open the Queue Manager
    my $self = shift; # take the handy hashref
    my $qm_name    = shift; # the name of the queue manager
    my $qm_ip         = shift; # the IP to the queue manager
    my $qm_port      = shift; # the port it's listening to
    my $qm_channel = shift; # the channel configured in the QM
    my $type           = shift; # request or reply? we will need it later

    # some validation code here making sure that the QM name, ip,
    # port, and channel have been provided 

    # export the MQSERVER environment variable just in case your clients need it
    $ENV{MQSERVER} = "$qm_channel/TCP/$qm_ip($qm_port)";

    # Here we create a MQSeries::QueueManager object to connect to our QM
    # It takes, among other parameters, the QM name, AutoConnect, and
    # a hashref with the data we gave to $ENV{MQSERVER}
    my $connOpts = {
          ChannelName => $qm_channel,
          TransportType => 'TCP',
          ConnectionName => "$qm_ip($qm_port)",
          MaxMsgLength   => 16 * 1024 * 1024,
    };

    # Create MQSeries::QueueManager object
    my $qm = MQSeries::QueueManager->new(
        QueueManager => $qm_name,
        AutoConnect => 0, # we do not autoconnect now
                          # because we want to handle it better later
        ClientConn => $connOpts,
    );

    #  kick it off and see if it connects
    eval {
        $qm->Connect()
            || die(sprintf("Connect failed with CompCode: %s",
                               Reason %sn",$qm->CompCode(),$qm->Reason()));
    };
    if ($@) { # eval caught the die
       confess($@);
   }

   # got this far, so it obviously connected
   # now save that connection in a safe place
   $self->{uc($type)}->{QM_CONN} = $qm; # MQSeries::QueueManager object.
                                        # We need it to open the queue
   $self->{uc($type)}->{QM_NAME} = $qm_name; # note that we also saved the QM_NAME and it is all under the $type (REQUEST/REPLY)

}
 ...
</pre>
<p>The snippet above showed you how to connect to the queue manager. It&#8217;s pretty well commented, so we can go on with our next step, which is opening the queue.</p>
<pre class="brush:perl">
...
sub openQueue() { # opens the Queue
    my $self       = shift;
    my $queue_name = shift;
    my $type       = shift; # again, we will need it for later.
                           # (REQUEST/REPLY)

    # set mode according to type
    my $mode = uc($type) eq 'REQUEST' ? 'output' : 'input';

    # open the queue directly this time
    # here we use the MQSeries::Queue module
    eval{
        $self->{uc($type)}->{Q_OBJ} =
           MQSeries::Queue->new(
               QueueManager  => $self->{uc($type)}->{QM_CONN}, # the QueueManager object from before
               Queue         => $queue_name,
               Mode         => $mode,
               AutoOpen         => 1, # open it directly
           )|| die("Could not open Queue $queue_name");
    };
    if ($@) {
        confess($@);
    }

    # made it this far, so we obviously got a connection
    # so let's save the queue name for later
    $self->{uc($type)}->{QUENAME} = $queue_name;
}
...
</pre>
<p>Now we have both our QueueManager and our Queue open. Since we&#8217;re dealing with one request pair and one reply pair, you&#8217;ll have to call it once for the request and once for the reply. You can also choose to save the connections in a different data structure to handle several queue managers and even more queues per queue manager. The only limit is your creativity. Right now, we&#8217;ll stick to the <tt>$self->{REQUEST}</tt> and <tt>$self->{REPLY}</tt> structures.</p>
<p>Continuing our layout, we now have to handle putting data into the queue.</p>
<pre class="brush:perl">
...
sub putRequest() { # puts the message
    my $self = shift;
    my $message = shift; # the data we will be putting

    # We need a MQSeries::Message object to inject
    my $msg =
        MQSeries::Message->new(
             MsgDesc => { # this is the MQMD (header) portion
				  Format	=> MQFMT_STRING,
				  Expiry	=> 100, # in tenths of seconds
				  ReplyToQ => $self->{REPLY}->{QUENAME},
				  ReplyToQMgr => $self->{REPLY}->{QM_NAME},
       				},
            Data => $message,
        );

    # now that we have a message object to inject, do the injecting
    my $request = $self->{REQUEST}->{Q_OBJ};
    eval {
       $request->Put(Message=>$msg) || die(sprintf("Put failed with CompCode: %s, Reason: %sn",
                                                            $request->CompCode(),$request->Reason()));
    };
    if($@){
        confess($@);
    }

    # got this far, so Put was successful. We'll return the MsgId to be used
    # as CorrelId when getting the reply
    return $msg->MsgDesc('MsgId'); # comes from the injected MQSeries::Message object
}
...
</pre>
<p>If you try printing the MsgId, you&#8217;ll get some funny characters in the screen, since it&#8217;s pure binary data. Look up &#8220;perl bin to hex&#8221; on Google if you&#8217;d like to see some ways of converting and not getting gibberish.</p>
<p>Next comes the last but not least portion of our module &#8211; to get the reply message.</p>
<pre class="brush:perl">
...
sub getReply() { # gets the reply using the correlId
    my $self      = shift;
    my $correlId = shift;

    # some sanity checking, since we can't do anything without $correlId
    confess("I need a correlId!!!n") unless $correlId;

    # create the Message object with the $correlId
    my $reply_msg =
            MQSeries::Message->new(
                 MsgDesc =>
				{
				    CorrelId	=> $correlId,
				},
            );

    my $reply_q = $self->{REPLY}->{Q_OBJ};
    eval {
       $reply_q->Get(
                     Message=> $reply_msg,
                     Wait => 100, # some interval before timing out
                ) || die(sprintf("Get message failed with CompCode: %s, Reason: %sn",
                                      $reply_q->CompCode(),$reply_q->Reason()));
    };
    if ($@){
        confess($@);
    }

    # got this far, so the Get was successful.
    # now we return the Data portion of the reply

    return $reply_msg->Data(); # from the Message object, not the Queue object!
}
...
</pre>
<p>And that&#8217;s all there is to the module! Now you can call it from your script, like so</p>
<pre class="brush:perl">
#!/usr/bin/perl

use strict;
use lib 'directory containing myMQModule';
use myMQModule;

# create object
my $mq = myMQModule->new();

# open queueMgr1
my($qm_name,$qm_ip,$qm_port,$qm_channel,$type) = qw(QMREQ some_ip some_port CHANNEL1 request);
$mq->openQueueMgr($qm_name,$qm_ip,$qm_port,$qm_channel,$type);

#open queueMgr2
($qm_name,$qm_ip,$qm_port,$qm_channel,$type) = qw(QMREP some_ip2 some_port2 CHANNEL2 reply);
$mq->openQueueMgr($qm_name,$qm_ip,$qm_port,$qm_channel,$type);

# now for the queues
$mq->openQueue('QUEUE1', 'request');
$mq->openQueue('QUEUE2', 'reply');

# put some message
my $msgId = $mq->putRequest('this is a test message');
my $reply_msg = $mq->getReply($msgId);

print "We're done!";
</pre>
<p>I really hope this was helpful. Comments are always welcome.</p>
<p>&nbsp;</p>
<h3>Book suggestions:</h3>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=12&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/05/perl-and-mqseries-for-the-faint-of-heart/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Perl Crash Course: Pragmas, Perl Modules, and CPAN</title>
		<link>http://usestrict.net/2009/05/perl-crash-course-pragmas-perl-modules-and-cpan/</link>
		<comments>http://usestrict.net/2009/05/perl-crash-course-pragmas-perl-modules-and-cpan/#comments</comments>
		<pubDate>Sun, 24 May 2009 01:00:14 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[Perl Course Howto]]></category>
		<category><![CDATA[perl crash course]]></category>
		<category><![CDATA[pragmas]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=475</guid>
		<description><![CDATA[About Perl Pragmas, Modules, and CPAN - the Comprehensive Perl Archive Network.]]></description>
			<content:encoded><![CDATA[<p>I always like to say that 90% of Perl is its modules. Back in 2000 when I was working as a junior Perl programmer I was asked to write a web application that, among other things, could send contact messages through email. Unfortunately, I never had anyone to really teach me the Path of Perl &#8211; I only relied on Learning Perl by Randall Schwartz, and whatever I could find on the net. I had a really hard time with that application, mainly because I didn&#8217;t know about Perl modules, MySQL and SQL language. Had I been familiar with at least the Perl modules part, I wouldn&#8217;t have had to spend 8 days and nights in the office (including my birthday). I didn&#8217;t even know how to <tt>use strict;</tt> at the time! Keep reading if <tt>use strict;</tt> makes no sense to you.</p>
<p>Being the extensible and flexible language that it is, Perl provides us with some safeguards and helpers to assist in avoiding what happened to me (I wish I knew that back then). The first of which I&#8217;ll talk about is Pragmas.<br />
<span id="more-475"></span></p>
<h2>Pragmas</h2>
<p>Pragmas are special modules that come installed by default in every Perl distribution. They tell the interpreter of how it is supposed to act. To turn them on, all you have to do is call the special word <tt>use</tt> with the appropriate Pragma. To turn them off, call <tt>no</tt> and the Pragma in question. The most common and powerful Pragma is, in my opinion, <tt>strict</tt> (hence the name of this blog: <tt>use strict;#)</tt>).</p>
<p>Strict tells the Perl interpreter that all variables must be declared and tightens up security a notch. To <tt>use strict;</tt> you have to have at least working knowledge of lexical variables. It takes a while to getting used to at first, but once you&#8217;re hooked, you won&#8217;t know how you could possibly have written Perl programs without it before (I know I don&#8217;t).</p>
<pre  class="brush:perl">
#!/usr/bin/perl

$var = 1; # OK
use strict;
$var1 = 2; # compile time error
</pre>
<p><em>example.pl</em></p>
<p>In our example above, Perl will refuse to run, raising a compile time error like such:</p>
<p><strong>Global symbol &#8220;$var1&#8243; requires explicit package name at example.pl line 5.<br />
Execution of example.pl aborted due to compilation errors.</strong></p>
<p>That&#8217;s <tt> strict</tt> in effect. Notice that <tt>$var</tt> was not cited, since <tt>strict</tt> was only enforced below it. In order to bypass that error, we should have declared our variable with either <tt>my</tt>, <tt>our</tt>, or <tt>local</tt> &#8211; depending on the need. <tt>my</tt> is the most common. Look up &#8220;Packages, Namespaces, and Lexical scopes&#8221; for more on those 3 operators.</p>
<pre  class="brush:perl">
#!/usr/bin/perl

$var = 1; # OK
use strict;
my $var1 = 2; # OK
</pre>
<p><tt>use strict;</tt> is so important that it is usually the second line of code in any decent Perl program &#8211; the first line being the <a href="javascript:;" title="shebang - comes from Hash (#) and Bang (!), which are the first 2 characters of the line. Tells *nix systems which program must be used to interpret the contents of the file. Shebang lines are ignored in Windows systems." >shebang</a>.</p>
<p>If you need to turn off <tt>strict</tt> for one reason or another, you can do so with the key word <tt>no</tt>.</p>
<pre  class="brush:perl">
#!/usr/bin/perl

use strict;
my $var = 1; # OK
no strict;
$var1 = 2; # also OK
</pre>
<p>When writing your Perl programs, it&#8217;s also good to turn on <tt>warnings</tt> and <tt>diagnostics</tt>. <tt>warnings</tt> will complain about possible problems such as useless uses of certain functions. <tt>diagnostics</tt>, on the other hand, will throw you a truckload of information regarding errors. It&#8217;s a good place to start when you&#8217;re stumped.</p>
<p>[ad#middle_end]</p>
<h2>Perl Modules</h2>
<p>Perl modules are pieces of code or packages that can be imported into your script with the keyword <tt>use</tt> in the same way as Pragmas. They can be Object Oriented, Procedural, or both. I will not discuss how to write a module in this post, but I <em>will</em> tell you where to find them for download and how to install them.</p>
<p>My all time favorite module is <a href="http://search.cpan.org/~ilyam/Data-Dumper-2.121/Dumper.pm" target="_blank">Data::Dumper</a>. So I will use it in the following examples. The funny <tt>::</tt> between Data and Dumper is kind of like a directory separator. The module Dumper resides in the directory Data, found in one of the paths configured in the Perl config files or the PERL5LIB environmental variable (which set the @INC array).</p>
<p>Data::Dumper comes installed by default, along with hundreds other modules that the developers deemed worthy. To test that your Perl distro has it, run the following command in a command line:</p>
<p><code>$ perl -MData::Dumper -e 'print "OKn"'</code></p>
<p>You&#8217;ll most definitely see the <code>OK</code> being printed on your screen. The command passes 2 parameters to the Perl interpreter: <code>-M</code> which tells it to load a module (in this case Data::Dumper &#8211; no spaces between -M and the module name, or you&#8217;ll get a &#8220;missing argument&#8221; error), and <code>-e</code> which tells it to execute a piece of code (we told it to print OK, but any valid piece of code would do).</p>
<p>Look at what would have happened if we tried to load a module that wasn&#8217;t installed:</p>
<p><code>$ perl -Maaaa -e 'print "OKn"'</code><br />
<strong>Can&#8217;t locate aaaa.pm in @INC (@INC contains: /usr/lib/perl5/5.10/i686-cygwin /usr/lib/perl5/5.10 /usr/lib perl5/site_perl/5.10/i686-cygwin /usr/lib/perl5/site_perl/5.10 /usr/lib/perl5/vendor_perl/5.10/i686-cygwin /usr/lib/perl5/vendor_perl/5.10 /usr/lib/perl5/vendor_perl/5.10 /usr/lib/perl5/site_perl/5.8 /usr/lib/perl5/vendor_perl/5.8 .).<br />
BEGIN failed&#8211;compilation aborted.</strong></p>
<p>To install a module, you can do it the hard way or the easy way. Some modules are harder than others, so I&#8217;ll stick with the easier ones for now. Let&#8217;s start with the hard way.</p>
<p>First, you should know where to find your module. <a href="http://www.cpan.org" target="_blank">CPAN &#8211; The Comprehensive Perl Archive Network</a> is the place to go to get your modules. It has a handy <a href="http://search.cpan.org" target="_blank">search engine</a> which will search through almost 16000 modules at the time of this writing (5/2009). There you will find code ranging from the most trivial to the craziest needs. If there&#8217;s one thing that CPANs contributors don&#8217;t lack, it&#8217;s creativity (that&#8217;s a compliment).</p>
<p>Enter a keyword in the search engine and it will list all relative modules. Click on the link to the one that interests you most. You will be shown its documentation in POD (Plain Old Documentation) format. That&#8217;s the data you will most likely need to learn how to use your module. It should also be the most up-to-date information, since it&#8217;s kept by its authors. </p>
<p>At the top of the POD screen, you&#8217;ll see a breadcrumb set of links showing the Author&#8217;s name, the module&#8217;s distribution name and version, and the module name itself:</p>
<p><a href="http://search.cpan.org/~ilyam/" target="_blank">Ilya Martynov</a> &gt;  <a href="http://search.cpan.org/~ilyam/Data-Dumper-2.121/" target="_blank">Data-Dumper-2.121 </a> &gt;  Data::Dumper </p>
<p>Click on the link for the module&#8217;s distribution name and version, to go to the distribution details screen. You will see lots of information about the module and its sub-modules, but what should concern you right now is the download link next to the release name. Click on it and download the module tarball.</p>
<p>Now this is where I halt and tell you that potential headaches lie ahead. There are basically 2 kinds of modules: PurePerl ones and C-based ones. PurePerl modules are just that &#8211; modules that are solely written in Perl. The vast majority of modules, however, are written in C with bindings special for Perl. Those usually have to be compiled and as such, need a C/C++ compiler and a <code>make</code> program. The good news is that most *nix systems come with those tools already installed or readily available. Windows systems, however, require that you install nmake and preferably Microsoft Visual C++. Check out my post about <a href="http://usestrict.net/2009/01/16/perl-installing-mqseries-module-on-windows-xp/" target="_blank">installing MQSeries module on Windows</a> for more information on how to get Microsoft Visual C++</p>
<p>Back to installing the module&#8230;</p>
<p>Unpack your module in some directory where you have full access. I like to keep an untouched copy of the tarball, by reading the gunzipped contents and throwing it to the screen with the <code>-c</code> option, and piping it to tar with <code>xvf -</code> parameters:</p>
<p><code>gunzip -c tarball.tar.gz | tar -xvf -</code></p>
<p>You&#8217;ll end up with a directory having the name of your distribution. Go in there and read all README files you can find. Read the INSTALL files if any.</p>
<p>One of the files you&#8217;ll see in the directory is <code>Makefile.PL</code>. That&#8217;s the kickoff file for the installation. It takes the following optional parameters: PREFIX, LIB, and INC, and creates a <code>makefile</code> tailor made for your system. It&#8217;s important to set the PREFIX parameter if you want the module installed in a place other than the default. LIB and INC point to the C lib and include directories, respectively.</p>
<p>Now that you have your <code>makefile</code>, it&#8217;s just a matter of running <code>make</code>, <code>make test</code>, and finally <code>make install</code>. Depending on the module, you should have no issues whatsoever. Other more &#8220;sensitive&#8221; modules, however, often require hours of work and even some tweaking of the makefiles by hand. <a href="http://search.cpan.org/~pythian/DBD-Oracle-1.23/Oracle.pm">DBD::Oracle</a> is by far the craziest module I&#8217;ve ever had to install. In some machines it&#8217;s a piece of cake, and others it manages to amuse with the amount of errors it pulls out of the hat. Anyway&#8230;</p>
<p>That was the hard way. Now for the easy way.</p>
<p>[ad#middle_end]</p>
<h2>CPAN</h2>
<p>If you&#8217;re finding it strange to see the CPAN title here when I&#8217;ve already talked about it above, don&#8217;t worry &#8211; I&#8217;m talking about the application CPAN and not the website.</p>
<p>Perl comes with the CPAN module installed, and most of the time it also creates a script in the bin directory called <code>cpan</code>. It&#8217;s an interactive shell that allows you to fetch information regarding authors and modules, and also allows you to install modules without having to go through the whole process of downloading the distribution, unpacking, etc.</p>
<p>Start up the CPAN application by calling </p>
<p><code>$ perl -MCPAN -e shell</code></p>
<p>If it&#8217;s the very first time you call it, you will be promped to answer a series of questions. Sticking to the default values is almost always OK. One of the first questions you will be asked is if you want CPAN to configure everything automatically. I recommend against it unless you know that the defaults are correct and will enable you to successfully install modules. And if you know that, then you probably already know how to use the CPAN application and this post has nothing new. <img src='http://usestrict.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Once the questions have been answered, you will be presented with a cpan prompt. Type <code>?</code> to know what options you have.</p>
<pre>cpan[1]> ?
Display Information                                                (ver 1.9205)
 command  argument          description
 a,b,d,m  WORD or /REGEXP/  about authors, bundles, distributions, modules
 i        WORD or /REGEXP/  about any of the above
 ls       AUTHOR or GLOB    about files in the author's directory
    (with WORD being a module, bundle or author name or a distribution
    name of the form AUTHOR/DISTRIBUTION)

Download, Test, Make, Install...
 get      download                     clean    make clean
 make     make (implies get)           look     open subshell in dist directory
 test     make test (implies make)     readme   display these README files
 install  make install (implies test)  perldoc  display POD documentation

Upgrade
 r        WORDs or /REGEXP/ or NONE    report updates for some/matching/all modu
les
 upgrade  WORDs or /REGEXP/ or NONE    upgrade some/matching/all modules

Pragmas
 force  CMD    try hard to do command  fforce CMD    try harder
 notest CMD    skip testing

Other
 h,?           display this menu       ! perl-code   eval a perl command
 o conf [opt]  set and query options   q             quit the cpan shell
 reload cpan   load CPAN.pm again      reload index  load newer indices
 autobundle    Snapshot                recent        latest CPAN uploads</pre>
<p>Use <code>o conf</code> to display the parameters to which you answered all those questions. You can change them with <code>o conf</code> as well. If you didn&#8217;t enable auto-commit before, you will have to call <code>o conf commit</code> to save your changes for use in future sessions.</p>
<p><code>o conf http_proxy "http://some_proxy.com:80"</code></p>
<p>The <code>m</code> command allows you to fetch information regarding a certain module.</p>
<pre>cpan[2]> m Data::Dumper
.... Possibly some data about fetching updated files from the internet here ....
Module id = Data::Dumper
    DESCRIPTION  Convert data structure into perl code
    CPAN_USERID  GSAR (Gurusamy Sarathy <gsar@cpan.org>)
    CPAN_VERSION 2.121
    CPAN_FILE    I/IL/ILYAM/Data-Dumper-2.121.tar.gz
    DSLIP_STATUS SdpOp (standard,developer,perl,object-oriented,Standard-Perl)
    MANPAGE      Data::Dumper - stringified perl data structures, suitable for b
oth printing and C<eval>
    INST_FILE    /usr/lib/perl5/5.10/i686-cygwin/Data/Dumper.pm
    INST_VERSION 2.121_14</pre>
<p>In the output above, CPAN tells us that we alreay have Data::Dumper version 2.121_14 installed. If you are not sure what is the exact name of a module, use the <code>i</code> command to fetch information using a regex:</p>
<pre>cpan[3]> i /klingon/
Distribution    JALDHAR/DateTime-Event-Klingon-1.0.1.tar.gz
Distribution    PNE/Lingua-Klingon-Collate-1.03.tar.gz
Distribution    PNE/Lingua-Klingon-Recode-1.02.tar.gz
Distribution    PNE/Lingua-Klingon-Segment-1.03.tar.gz
Module    DateTime::Event::Klingon (JALDHAR/DateTime-Event-Klingon-1.0.1.tar.gz)

Module    Lingua::Klingon::Collate (PNE/Lingua-Klingon-Collate-1.03.tar.gz)
Module    Lingua::Klingon::Recode (PNE/Lingua-Klingon-Recode-1.02.tar.gz)
Module    Lingua::Klingon::Segment (PNE/Lingua-Klingon-Segment-1.03.tar.gz)
8 items found</pre>
<p>Once you&#8217;re happy with the module name, you can check if it&#8217;s installed or not using <code>m</code></p>
<pre>cpan[4]> m Lingua::Klingon::Collate
Module id = Lingua::Klingon::Collate
    CPAN_USERID  PNE (Philip Newton
<pne@cpan.org>)
    CPAN_VERSION 1.03
    CPAN_FILE    P/PN/PNE/Lingua-Klingon-Collate-1.03.tar.gz
    INST_FILE    (not installed)</pre>
<p>Install it with <code>install</code> command.</p>
<p><code>cpan[5] install Lingua::Klingon::Collate</code></p>
<p>Now, unless you already have module Test::Differences installed, Lingua::Klingon::Collate will fail with a dependency error. Not all modules are like that. Some are coded in a way that CPAN actually asks you if you want to follow and install dependencies automagically. Those are a cinch to install.</p>
<p>If something goes wrong, look at the output of the installation. Best case scenario, you&#8217;re just missing another module and it didn&#8217;t warn you about it. For example, after Lingua::Klingon::Collate failed with the warning that I should have Test::Differences installed, I tried to install that dependency directly. It also failed. When looking at the output on the screen, I see a bunch of lines like this:</p>
<pre>
t/regression..........Can't locate Text/Diff.pm in @INC (@INC contains: /home/vi
alves/.cpan/build/Test-Differences-0.4801-lI_xia/blib/lib /home/vialves/.cpan/bu
ild/Test-Differences-0.4801-lI_xia/blib/arch /usr/lib/perl5/5.10/i686-cygwin /us
r/lib/perl5/5.10 /usr/lib/perl5/site_perl/5.10/i686-cygwin /usr/lib/perl5/site_p
erl/5.10 /usr/lib/perl5/vendor_perl/5.10/i686-cygwin /usr/lib/perl5/vendor_perl/
5.10 /usr/lib/perl5/vendor_perl/5.10 /usr/lib/perl5/site_perl/5.8 /usr/lib/perl5
/vendor_perl/5.8 .) at /home/vialves/.cpan/build/Test-Differences-0.4801-lI_xia/
blib/lib/Test/Differences.pm line 213.
</pre>
<p>You&#8217;ll notice that the error is the same as when we did the <code>$ perl -Maaaa -e 'print "OK"'</code>. Module Text/Diff.pm (or namely Text::Diff) is not installed. So we now go on that quest of following dependencies by hand. </p>
<p>It so happens that Test::Differences tried to install Text::Diff, but Text::Diff failed during the test phase. Suppose I know that those failed tests are not important and won&#8217;t hinder the results of the rest (I don&#8217;t, but bare with me), I can force CPAN to disregard the test failures:</p>
<pre>
cpan[6]> force install Text::Diff
Running install for module 'Text::Diff'
Running make for R/RB/RBS/Text-Diff-0.35.tar.gz
  Has already been unwrapped into directory /home/vialves/.cpan/build/Text-Diff-
0.35-B8Qsuo
  Has already been made
Running make test
/usr/bin/perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'b
lib/arch')" t/*.t
t/ext_format......ok
t/general.........Use of /g modifier is meaningless in split at t/general.t line
 129.
Use of /g modifier is meaningless in split at t/general.t line 130.
t/general.........ok
t/inputs..........ok
t/keygen..........ok
t/outputs.........1/8 No such file or directory at t/outputs.t line 12, <SLURP>
line 6.
t/outputs......... Dubious, test returned 2 (wstat 512, 0x200)
 Failed 4/8 subtests
t/table...........ok

Test Summary Report
-------------------
t/outputs.t   (Wstat: 512 Tests: 4 Failed: 0)
  Non-zero exit status: 2
  Parse errors: Bad plan.  You planned 8 tests but ran 4.
Files=6, Tests=29,  1 wallclock secs ( 0.04 usr  0.04 sys +  0.59 cusr  0.26 csy
s =  0.93 CPU)
Result: FAIL
Failed 1/6 test programs. 0/29 subtests failed.
make: *** [test_dynamic] Error 255
  RBS/Text-Diff-0.35.tar.gz
  /usr/bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
  reports RBS/Text-Diff-0.35.tar.gz
Running make install
Installing /usr/lib/perl5/site_perl/5.10/Text/Diff.pm
Installing /usr/lib/perl5/site_perl/5.10/Text/Diff/Table.pm
Writing /usr/lib/perl5/site_perl/5.10/i686-cygwin/auto/Text/Diff/.packlist
Appending installation info to /usr/lib/perl5/5.10/i686-cygwin/perllocal.pod
  RBS/Text-Diff-0.35.tar.gz
  /usr/bin/make install  -- OK
Failed during this command:
 RBS/Text-Diff-0.35.tar.gz                    : make_test FAILED but failure ign
ored because 'force' in effect
</pre>
<p>Now I can go on to installing Text::Differences and finally Lingua::Klingon::Collate.</p>
<pre>cpan[7] install Test::Differences
.... some output here ....
Appending installation info to /usr/lib/perl5/5.10/i686-cygwin/perllocal.pod
  OVID/Test-Differences-0.4801.tar.gz
  /usr/bin/make install  -- OK

cpan[8] install Lingua::Klingon::Collate
Running install for module 'Lingua::Klingon::Collate'
Running Build for P/PN/PNE/Lingua-Klingon-Collate-1.03.tar.gz
  Has already been unwrapped into directory /home/vialves/.cpan/build/Lingua-Kli
ngon-Collate-1.03-MX7FZn
  -- No Build created, won't make
Running Build test
  Make had some problems, won't test
Running Build install
  Make had some problems, won't install</pre>
<p>Ok, that happens. It&#8217;s because of the previous bad attempt. We can bypass that by telling CPAN to restart the build from scratch. To do so, it must first clean the build environment for that module.</p>
<p><code><br />
cpan[9] clean Lingua::Klingon::Collate<br />
</code></p>
<p>That usually does the trick and enables you to run the <code>install</code> again, but if it doesn&#8217;t, you can <code>force get Lingua::Klingon::Collate</code> to get a fresh package.</p>
<pre>
cpan[27]> install Lingua::Klingon::Collate
Running install for module 'Lingua::Klingon::Collate'
Running Build for P/PN/PNE/Lingua-Klingon-Collate-1.03.tar.gz
  Has already been unwrapped into directory /home/vialves/.cpan/build/Lingua-Kli
ngon-Collate-1.03-ZA4a1s

  CPAN.pm: Going to build P/PN/PNE/Lingua-Klingon-Collate-1.03.tar.gz

Checking whether your kit is complete...
Looks good

Checking prerequisites...
Looks good

Creating new 'Build' script for 'Lingua-Klingon-Collate' version '1.03'
Copying lib/Lingua/Klingon/Collate.pm -> blib/lib/Lingua/Klingon/Collate.pm
Manifying blib/lib/Lingua/Klingon/Collate.pm -> blib/libdoc/Lingua.Klingon.Colla
te.3pm
HTMLifying blib/lib/Lingua/Klingon/Collate.pm -> blib/libhtml/site/lib/Lingua/Kl
ingon/Collate.html
./Build: blib/lib/Lingua/Klingon/Collate.pm: cannot resolve L<strcoll(3)> in par
agraph 60.
./Build: blib/lib/Lingua/Klingon/Collate.pm: cannot resolve L<strxfrm(3)> in par
agraph 60.
  PNE/Lingua-Klingon-Collate-1.03.tar.gz
  ./Build -- OK
Running Build test
t/01_base...........ok
t/02_strcoll........ok
t/03_strxfrm........ok
t/04_strunxfrm......ok
t/05_list...........ok
All tests successful.
Files=5, Tests=87,  1 wallclock secs ( 0.05 usr  0.03 sys +  0.52 cusr  0.25 csy
s =  0.85 CPU)
Result: PASS
  PNE/Lingua-Klingon-Collate-1.03.tar.gz
  ./Build test -- OK
Running Build install
Prepending /home/vialves/.cpan/build/Lingua-Klingon-Collate-1.03-ZA4a1s/blib/arc
h /home/vialves/.cpan/build/Lingua-Klingon-Collate-1.03-ZA4a1s/blib/lib to PERL5
LIB for 'install'
Installing /usr/lib/perl5/site_perl/5.10/Lingua/Klingon/Collate.pm
Installing /usr/share/man/man3/Lingua.Klingon.Collate.3pm
Installing /usr/share/doc/perl-5.10.0/html/html3/site/lib/Lingua/Klingon/Collate
.html
Writing /usr/lib/perl5/site_perl/5.10/i686-cygwin/auto/Lingua/Klingon/Collate/.p
acklist
  PNE/Lingua-Klingon-Collate-1.03.tar.gz
  ./Build install  -- OK</pre>
<p>Type <code>q</code> to exit the shell and that&#8217;s it! There are many other options when using CPAN, but what you&#8217;ve seen so far in this post should be enough to get you started. Just remember to use <code>?</code> every now and then to see what powers are offered to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/05/perl-crash-course-pragmas-perl-modules-and-cpan/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Perl Crash Course: Control Structures</title>
		<link>http://usestrict.net/2009/04/perl-crash-course-control-structures/</link>
		<comments>http://usestrict.net/2009/04/perl-crash-course-control-structures/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 03:06:22 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Control Structures]]></category>
		<category><![CDATA[Perl Course Howto]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=409</guid>
		<description><![CDATA[Basics on Perl control structures]]></description>
			<content:encoded><![CDATA[<p><strong>by André Batosti<br />
revision: Fernando Giorgetti and Vinny Alves</strong></p>
<p>Control Structures are used to control the flow of a program. We are going to see programs that can iterate (loop) or make decisions (conditionals) based on the state of variables.</p>
<p>More interesting possibilities arise when we introduce control structures and looping. Perl supports lots of different kinds of control structures which tend to be like those in C, but are very similar to Pascal, too.<br />
<span id="more-409"></span><br />
<code><br />
</code></p>
<h3>Conditionals</h3>
<p>The simplest control structures are the <tt>if</tt> and <tt>unless</tt> statements. Its syntax basically follows the rule below:</p>
<pre name="code" class="php">
if ( expression ) {
    instruction1;
    instruction2;
}
</pre>
<p>Value obtained from &#8220;expression&#8221;, determines whether it will be considered as <tt>true</tt> or <tt>false</tt>. Table below helps you to identify the meaning of values based on how Perl interprets expressions.</p>
<table border="1" cellpadding="0">
<tbody>
<tr>
<td><strong>Expression</strong></td>
<td><strong>String/Number?</strong></td>
<td><strong>Boolean value</strong></td>
</tr>
<tr>
<td>0</td>
<td>number</td>
<td>false</td>
</tr>
<tr>
<td>0.0</td>
<td>number</td>
<td>false</td>
</tr>
<tr>
<td>0.0000</td>
<td>number</td>
<td>false</td>
</tr>
<tr>
<td>&#8220;&#8221; or &#8221;</td>
<td>string</td>
<td>false</td>
</tr>
<tr>
<td>&#8220;0&#8243;</td>
<td>string</td>
<td>false</td>
</tr>
<tr>
<td>&#8220;0.0&#8243;</td>
<td>string</td>
<td><strong>true</strong></td>
</tr>
<tr>
<td>undef</td>
<td>N/A</td>
<td>false</td>
</tr>
<tr>
<td>42 &#8211; (6 * 7)</td>
<td>number</td>
<td>false</td>
</tr>
<tr>
<td>&#8220;0.0&#8243; + 0.0</td>
<td>number</td>
<td><strong>false</strong></td>
</tr>
<tr>
<td>&#8220;0E0&#8243;</td>
<td>number</td>
<td><strong>true</strong></td>
</tr>
<tr>
<td>0E0</td>
<td>number</td>
<td><strong>false</strong></td>
</tr>
<tr>
<td>&#8220;foo&#8221;</td>
<td>string</td>
<td>true</td>
</tr>
</tbody>
</table>
<p>Everything in Perl is true, except:</p>
<ul type="disc">
<li>the strings &#8220;&#8221; (the empty string) and &#8220;0&#8243; (the string containing only the character, 0), or any string expression that evaluates to either &#8220;&#8221; (the empty string) or &#8220;0&#8243;.</li>
<li>any numeric expression that evaluates to a numeric 0.</li>
<li>any value that is not defined (i.e., equivalent to undef).</li>
</ul>
<p>A very simple example of a real &#8220;if statement&#8221; would be:</p>
<pre name="code" class="php">
if ( $name ) {
    print "Non empty string";
}
else {
    print "Empty string";
}
</pre>
<p>Another example, to illustrate the syntax of the &#8220;if&#8221; statement:</p>
<pre name="code" class="php">
if ( $money &lt;= 0 ) {
    print "You are out of money";
}
elsif ( $money &gt; 1000000 ) {
    print "You are a millionaire";
}
else {
    print "You are probably better than I am";
}
</pre>
<p>Blocks of code in Perl are enclosed by curly braces {   }. They are <strong>always required</strong> inside a control structure (except for cases where we use idiomatic ifs &#8211; see more below).</p>
<p>Two things to mention:</p>
<p>1 &#8211; <tt>elsif</tt> spelling;<br />
2 &#8211; both <tt>elsif</tt> and <tt>else</tt> statements are optional.</p>
<p>Another conditional statement we need to mention is the <tt>unless</tt>. Its meaning is the opposite of an <tt>if</tt> statement. It will only execute a block of code if expression is NOT true.</p>
<p>Let&#8217;s look at an example:</p>
<pre name="code" class="php">
if  ( $num == 10 ) { #Usual if statement
    print "Number is equal to 10";
} else {
    print "Number not equal to 10";
}

# Unless statement that will execute the block of code below
# if number's value is not 10 (same thing as the else statement above)

unless ( $num == 10 ) {
    print "Number not equal to 10";
}
else {
    print "Number is equal to 10";
}
</pre>
<h3>Action based on statement test</h3>
<p>You can test a single statement and perform a pre-defined action in case it is true or another one if statement is false.</p>
<p>For example:</p>
<pre name="code" class="php">
    print "You are a man" if ($gender eq "M"); # parentheses are optional here, since only one expression is evaluated
</pre>
<p><code><br />
</code><br />
[ad#middle_end]<br />
<code><br />
</code></p>
<h3>Ternary or Trinary Operator</h3>
<p>Like many other programming languages, Perl offers the ternary (aka trinary) operator &#8220;?:&#8221; which behaves just like if/elsif/else: </p>
<pre name="code" class="php">
print "You are a " . (($gender eq "M") ? "man" : "woman") . "n";
# read: if $gender eq "M" then "man" else "woman"

# or perhaps
($birthday == $today) ? print "Happy birthday!" : print "Have a good day";
</pre>
<p>Mimmic elsif this way:</p>
<pre name="code" class="php">
$month = (localtime)[4]; # fifth element of localtime in list context returns month, base 0;

print "The month is now " .
($month == 0) ? "January" :
($month == 1) ? "February" :
($month == 3) ? "March" :
                      "something other than Jan, Feb, or March";
</pre>
<h3>Operators</h3>
<p>Initially we will introduce the testing operators. They rely on a test being considered as true or false. Following you can see a few examples:</p>
<pre name="code" class="php">
$a == $b                      # Is $a numerically equal to $b?
# Beware: Don't use the = operator.
$a != $b                       # Is $a numerically unequal to $b?
$a eq $b                       # Is $a string-equal to $b?
$a ne $b                       # Is $a string-unequal to $b?
</pre>
<p>Perl also supports the logical operators &#8220;OR&#8221; and &#8220;AND&#8221;. The &#8220;OR&#8221; operator is represented by the &#8220;||&#8221; characters while the &#8220;AND&#8221; is represented by &#8220;&amp;&amp;&#8221; characters.</p>
<p>Lets go through a few examples:</p>
<pre name="code" class="php">
# If value of number is greater than 10 or lesser than 5
if ( ( $num &gt; 10 ) || ( $num &lt; 5 ) ) {
    ...
}

# If language is equal to "perl" and num is 10, or, if num is 0 (or has a "false" value)
if ( (( $language eq "perl" ) &amp;&amp; ( $num == 10 )) || !( $num ) ) {
    ...
}
</pre>
<h3>Loops</h3>
<p>We have several statements to perform iterations using Perl. Perl supports: <tt>while</tt>, <tt>until</tt>, <tt>do ... while</tt>, <tt>for</tt> and <tt>foreach</tt> statements.</p>
<h3><em>While</em></h3>
<p>Performs the iteration while the given expression is true. Syntax:</p>
<pre name="code" class="php">
while (expression) {
    instruction1;
    instruction2;
    ...
}
</pre>
<h3><em>Until</em></h3>
<p>It is the opposite of <tt>while</tt>. So take it as, in example:</p>
<pre name="code" class="php">
while (!(expression)) {
    instruction1;
    instruction2;
}

#same as
until (expression) {
   instruction1;
   instruction2;
}
</pre>
<h3><em>Do .. While</em></h3>
<p>Its functionality is almost the same as for the normal &#8220;while&#8221; statement, but with this kind of control structure you guarantee that the block of code will be executed at least once.</p>
<pre name="code" class="php">
do {
    instruction1;
    instruction2;
} while (expression);
</pre>
<h3><em>For</em></h3>
<p>It&#8217;s a C like style. Syntax:</p>
<pre name="code" class="php">
for (initialize; expression; increment/decrement) {
    instruction1;
    instruction2;
    ...
}
</pre>
<ul type="disc">
<li>The <em>initialize</em> statement is basically used to initialize the variable that will be used on the test statement. It can also be used anywhere in the block. Declare it with <tt>my</tt> to keep it private to the for block;</li>
<li><em>Expression</em> follows the same rule for <tt>if</tt> or <tt>while</tt>. It will be tested, and if its return is true, block code will be executed;<em></em></li>
<li><em>Increment/decrement </em>is then executed<em></em></li>
</ul>
<p>Real example:</p>
<pre name="code" class="php">
for ($i = 0; $i &lt; 10; $i++ ) {
    printf "Iteration number: %sn", $i;
}
</pre>
<p>Another good example (not using a numeric expression):</p>
<pre name="code" class="php">
for ( @names = ('John', 'Paul', 'Roger', 'David'); @names; shift(@names) ) {
    print "$names[0]n";
}

# Or work on 2 expressions at the same time
for ($i = 0, $j = 10; $i&lt;=10,$j&gt;=0; $i++, $j--) {
    print "$i    $jn";
}

# Or kick off an infinite loop
for ( ; ; ) {
    instruction1;
    instruction2;
}
</pre>
<h3><em>Foreach</em></h3>
<p>It is another control structure that allows iteration, but here you can iterate over an array.</p>
<p>Following you can see a few examples of it:</p>
<pre name="code" class="php">
@names = ('John', 'Paul', 'Roger', 'David');

#Passing through all names
foreach $name (@names) {
    printf "%sn", $name;
}
</pre>
<p>The scalar variable is optional to the <tt>foreach</tt> statement. So you can bypass it by doing:</p>
<pre name="code" class="php">
@names = ('John', 'Paul', 'Roger', 'David');

#Passing through all names
foreach (@names) {
    printf "%sn", $_;
}
</pre>
<p>If you don&#8217;t specify a scalar variable to get each iteration, then the default scalar ($_) will be used. Note that <tt>for</tt> can also be used as a synonym to <tt>foreach</tt> &#8211; same exact functionality, but without the <em>each</em> portion of the word.</p>
<h3><em>Loop flow control</em></h3>
<p>We have a few special commands to help us controlling the flow under a loop statement. Here we go.</p>
<p><tt>last</tt></p>
<p>It is similar to the &#8220;break&#8221; statement used on C programming language (as well as in several others). Tells Perl to skip the current loop statement, or even, to skip a labeled loop statement. Take a look at the example below:</p>
<pre name="code" class="php">
@names = ('fernando', 'smith', 'Mark', 'John');
foreach (@names) {
    last if $_ eq "John";
    print "Name is " . $_ . "n";
}
</pre>
<p><tt>next</tt></p>
<p><tt>next</tt> has the same function as the &#8220;continue&#8221; loop statement used in C. Used to force your loop statement to go to the next iteration. In example:</p>
<pre name="code" class="php">
@names = ('fernando', 'smith', 'Mark', 'John');
foreach (@names) {
    next if $_ eq "smith";
    print "Name is " . $_ . "n";
}
</pre>
<p>The example above will just force the &#8220;foreach&#8221; statement to read next iteration once &#8220;smith&#8221; is the value read from the &#8220;names&#8221; array.</p>
<p>If you need to work on multiple levels of loops, you can tell <tt>next</tt> and <tt>last</tt> which named block to work on:</p>
<pre name="code" class="php">
LINE: while (<STDIN>) {
	next LINE if /^#/;	# discard comments
	...
}
</pre>
<p>[ad#middle_end]</p>
<p style="text-align:right;"><a href="http://usestrict.net/2009/04/07/perl-crash-course-basic-regular-expressions/">« Basic Regular Expressions</a> | <a href="http://usestrict.net/2008/10/05/perl-crash-course/" target="_self">TOC</a> | Basic I/O »</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/04/perl-crash-course-control-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl Crash Course: Subroutines</title>
		<link>http://usestrict.net/2009/03/perl-crash-course-subroutines/</link>
		<comments>http://usestrict.net/2009/03/perl-crash-course-subroutines/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 23:27:32 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Course Howto]]></category>
		<category><![CDATA[perl crash course]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=294</guid>
		<description><![CDATA[Introduction Subroutines are user-created functions that execute a block of code at any given place in your program. It is a best practice, however, to aggregate them all either at the beginning or the end the main program. Subroutine declarations initiate with the key word &#8220;sub&#8221; . Conventionally, subroutine names are all lowercase characters sub [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>Subroutines  are user-created functions that execute a block of code at any given place in your program. It is a best practice, however, to aggregate them all either at the beginning or the end the main program.</p>
<p>Subroutine declarations initiate with the key word &#8220;sub&#8221; . Conventionally, subroutine names are all lowercase characters</p>
<p>sub NAME (PROTOTYPE) BLOCK</p>
<pre class="php" name="code">print_hello; <b># subroutine can be executed/called before the actual block is created</b>

sub print_hello {
      print "Hello worldn";
}</pre>
<p>When we called <em>print_hello</em> we told Perl that we wanted the piece of code named print_hello to be executed. The result is a &#8220;Hello World&#8221; showing up on our screen. The only benefit we have from that snippet in its current form is that we won&#8217;t have to copy/paste the print statement all over our script if we want to repeat it. All we need to do is call <em>print_hello</em>;<br />
<span id="more-294"></span><br />
Another, older, but still common form of calling it would be</p>
<pre class="php" name="code">&amp;print_hello;</pre>
<h3>Parameters</h3>
<p>As mentioned before, our previous example doesn&#8217;t do much by itself. The good news is that subroutines can take a list of parameters and do something based on what it receives. Let&#8217;s change our example for something a little better:</p>
<pre class="php" name="code">$me = "Vinny";

print_hello($me);

sub print_hello {
	$name = shift;
	print "Hello $namen";
}

<b># prints out "Hello Vinny"</b></pre>
<p>Let&#8217;s take a closer look at that. During my subroutine call, I&#8217;m passing it a list of 1 element &#8220;Vinny&#8221;.  That element is populated into the special array <tt>@_</tt>, which is then passed into the subroutine. Like <tt>$_</tt>, you don&#8217;t have to explicitly point out <tt>@_</tt> when using certain array functions.  In our example, we <tt>shift</tt>ed the first element of <tt>@_</tt> into our variable <tt>$name</tt> and printed it out.</p>
<p>It would have been possible to work directly against <tt>$_[0]</tt>, yes, but doing so might be dangerous depending on what you&#8217;re doing. Here&#8217;s why: there are 2 ways of passing parameters into a subroutine.</p>
<p>The first and more common is <em>pass-by-value</em>. Pass-by-value is when we use the value of <tt>$_[0]</tt> into a variable of our own declared within the subroutine. Due to the lexical nature of subroutines (<tt>$name</tt> doesn&#8217;t exist outside of the subroutine in our example &#8211; we&#8217;ll see more about that later), the original variable (<tt>$me</tt>) is untouched.</p>
<p>The second and possibly dangerous way of doing it is by using the <em>pass-by-reference</em> method. In this case, we work against <tt>$_[0]</tt> directly, which is a reference to the variable passed. Any changes to<tt> $_[0]</tt> will affect the contents of <tt>$me</tt>. This is typically NOT what you want to do.</p>
<pre class="php" name="code">$me = "Vinny";

print_hello($me);
print "$men";

sub print_hello {
    print "Hello $_[0]n";
    $_[0] .= " Alves";
}</pre>
<p>When passing more complex structures such as hashes and arrays, bear in mind that Perl flattens them out into a single array by default.</p>
<pre class="php" name="code">@myArray = qw(red green blue);

%myHash = ('apple'=&gt;'fruit',  'dog' =&gt;'pet');

print_hello(@myArray,%myHash);

sub print_hello {
	for $i (@_) {
		print "Got $in";
	}
}
<b># Prints :
# red
# green
# blue
# apple
# fruit
# dog
# pet</b></pre>
<p>Again, that&#8217;s probably not what you wanted. To maintain the individuality and structure of your elements, you will need to pass a reference to each element as parameters, and then assign them to variables in your subroutine.</p>
<pre class="php" name="code">
print_hello(@myArray,%myHash);

sub print_hello {

	$array_ref = shift;
	$hash_ref = shift;

	for $fruit (@$array_ref) {
		print "Got $fruitn";
	}

	print "A dog is a " . $hash_ref-&gt;{dog} . "n";
}</pre>
<h3>Returning Data</h3>
<p>Subroutines are handy for returning some sort of data. By default, it returns 0 or 1 if the keyword <tt>return</tt> isn&#8217;t found &#8211; depending on the success or failure of the subroutine. Optionally, you can have it return a specific piece of data, such as a scalar, a list/array or reference to arrays, hashes, scalars, etc. The same rules we find in passing parameters apply to returning data.</p>
<pre name="code" class="php">
#!/usr/bin/perl

$num1 = 10;
$num2 = 5;
$result = compare($num1,$num2);

print $result; <b># "is greater"</b>

sub compare {
    return "is greater" if $_[0] > $_[1];
    return "is smaller" if $_[0] < $_[1];
    return "is equal"  if $_[0] == $_[1];
}
</pre>
<p>Here is another way to see the same results:</p>
<pre name="code" class="php">
#!/usr/bin/perl

use strict;

$num1 = 10;
$num2 = 5;
$result = compare($num1,$num2);

print $result; # "is greater"

sub compare(@) {
	if ($_[0] > $_[1]) {
		"is greater"; # "return" operator not required
	}
	elsif($_[0] == $_[1]) {
		"is equal";
	}
	else {
		"is less than";
	}
}
</pre>
<p>As you can see, we didn't use the <tt>return</tt> operator in the example above. It is not required here because Perl will automatically return the value of the last statement evaluated. It's not a best practice to do it this way though. We strongly recommend that you keep your <tt>return</tt>s where they're supposed to be.</p>
<p>[ad#middle_end]</p>
<h3>Prototypes</h3>
<p>In order to bypass the flattening out of all the array and hash parameters into a single array, Perl allows us to specify prototypes for our subroutines. This tells our program if we're expecting an Array, or a Hash, or to treat the elements passed as individual references instead of flattening them out. It also lets us define which parameters are mandatory and which are optional.</p>
<p>There are ways of overriding (turning off) prototypes. By calling the subroutine in the "old" fashion (&amp;my_proto; or &amp;my_proto()) for instance, the checking will not be done. Calling subroutines as methods in Object Oriented Perl also turns it off.</p>
<p>The catch with prototypes is that you have to declare the subroutine BEFORE actually calling it. Look at the following example:</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

@array = qw(a b c );

my_proto(@array,'test');

sub my_proto(@) {
	print "@_n";
}
<b># Warns the following message:  main::my_proto() called too early to check prototype at ./test.pl line 5.
# and prints "a b c test"</b>
</pre>
<p>In this example, the subroutine and its prototype are declared after the call. Perl warns that the call was too early to check prototype and treats the subroutine as if it didn't have any.  The correct way of doing it would be this:</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

sub my_proto(@); <b># pre-declare the sub</b>

@array = qw(a b c );
my_proto(@array,'test');

sub my_proto(@) {
	print "@_n";
}
<b># Compilation error:
# Too many arguments for main::my_proto at ./test.pl line 8, near "'test')"
# Execution of ./test.pl aborted due to compilation errors.</b>
</pre>
<p>This time the script didn't even compile (remember that Perl is an interpreted AND compiled language). Prototype checking was in place and raised the error which aborted compilation.</p>
<p>You probably realized that the error message we got is the same as the ones we get when we fail to provide built-in functions the right parameters. That's exactly what prototyping does - it allows you to make your subroutines behave like built-in functions.</p>
<p>The <a href="http://perldoc.perl.org/perlsub.html#Prototypes" target="_blank">perlsub section in perldoc</a> shows the kinds of prototypes that we can use to mimick the built-in functions:</p>
<pre>
		Declared as		Called as

		sub mylink ($$)		mylink $old, $new
		sub myvec ($$$)		myvec $var, $offset, 1
		sub myindex ($$;$)	myindex &amp;getstring, "substr"
		sub mysyswrite ($$$;$)	mysyswrite $buf, 0, length($buf) - $off, $off
		sub myreverse (@)	myreverse $a, $b, $c
		sub myjoin ($@)		myjoin ":", $a, $b, $c
		sub mypop (@)		mypop @array
		sub mysplice (@$$@)	mysplice @array, @array, 0, @pushme
		sub mykeys (%)		mykeys %{$hashref}
		sub myopen (*;$)	myopen HANDLE, $name
		sub mypipe (**)		mypipe READHANDLE, WRITEHANDLE
		sub mygrep (&amp;@)		mygrep { /foo/ } $a, $b, $c
		sub myrand (;$)		myrand 42
		sub mytime ()		mytime
</pre>
<p><strong>Notes:</strong></p>
<ul>
<li>';' is used to separate mandatory (to the left of ; ) from optional fields (to the right).</li>
<li>@, $, %, etc. makes the sub require that exact element in the position in which it was declared.</li>
<li>sub mysub([@$%]) allows you to call mysub with a $var, or @array, or %hash, etc.</li>
<li>sub mysub($) when called with mysub(@array) will <strong>force the array to be handled in SCALAR context</strong></li>
</ul>
<p>Another catch of declaring subs with prototypes is that you will get a warning if you declare your sub with a given prototype first, and then again with the rest of the code and a different prototype. Let's look at a couple of examples to get a better idea of what I mean.</p>
<p><strong>Example 1</strong></p>
<pre class="php" name="code">
#!/usr/bin/perl -w

sub mysub(@); <b># defined in array context</b>

@array = qw(a b c);

mysub(@array);

sub mysub($) {  <b># defined in scalar context</b>
	print "@_n";
}
<b># Prototype mismatch: sub main::mysub (@) vs ($) at ./test.pl line 15.
# prints out "a b c"</b>
</pre>
<p><strong>Example 2</strong></p>
<pre class="php" name="code">
#!/usr/bin/perl -w

sub mysub($) {  <b># defined in scalar context</b>
	print "@_n";
}

@array = qw(a b c);

mysub(@array);

<b># works just fine
# prints out "3" due to the scalar context in which the sub is defined.</b>
</pre>
<h3>Lexical Scopes</h3>
<p>Perl by default is a very loose language. It lets you get away with things that other languages would never dream of - like using global variables indiscriminately. It's all fine and good if you want to write a quick and dirty script that isn't more than a few lines long, but if you're trying to build a complex application such as a bulletin board system (Matt Wright's wwwboard was written in (horrible) perl), you will probably find yourself missing a few toes after all the shots you foot took.</p>
<p>A solution for this problem is to ALWAYS use strict. Strict is a pragmatic module (or just pragma) that enforces several security measures such as having to pre-declare your variables, and another large list of constraints. It should always be the second line of your program (being the shebang the first line).</p>
<p>One of the things that use strict; enforces the most is to have you make good usage of lexical scopes. Lexical scopes mean that you can't access a variable that was not pre-declared, or somehow imported into the current block of code.</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

$name = 'vinny';

myprint();

sub myprint() {
	print "$namen";
}
<b># main::myprint() called too early to check prototype at ./test.pl line 7.
# vinny</b>
</pre>
<p>The example above accesses the value of the global variable $name from within the subroutine. That is not a very safe thing to do. If we turn on strict, we get an error when trying to do that. The error, however, is because we didn't declare $name with either my, local, or our.</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

use strict;

$name = 'vinny';

myprint();

sub myprint() {
	print "$namen";
}

<b># main::myprint() called too early to check prototype at ./test.pl line 7.
# Global symbol "$name" requires explicit package name at ./test.pl line 5.
# Global symbol "$name" requires explicit package name at ./test.pl line 11.
# Execution of ./test.pl aborted due to compilation errors.</b>
</pre>
<p>Changing the script above to comply with strict, we are once again able to access the global $name, but we still don't want to do that, especially if we want to modify the value of $name only inside the subroutine.</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

use strict;

my $name = 'vinny'; <b># added my to comply with strict</b>

myprint();

print "$namen";

sub myprint() {
	$name .= " Alves"; <b># changes the original variable instead of a private one</b>
	print "$namen";
}

<b># main::myprint() called too early to check prototype at ./test.pl line 7.
# vinny Alves
# vinny Alves</b>
</pre>
<p>So it's best if we play it safe and not work on global variables at all. This is especially the case if you one day plan on writing scripts to use with Apache/mod_perl.</p>
<pre class="php" name="code">
#!/usr/bin/perl -w

use strict;

my $name = 'vinny'; <b># added <tt>my</tt> to comply with strict</b>

myprint($name); <b># calls the sub</b>

print "$namen"; <b># $name here still has the original value</b>

sub myprint() {
	my $name = shift;
	$name .= " Alves";
	print "$namen";
}
<b># main::myprint() called too early to check prototype at ./test.pl line 7.
# vinny Alves
# vinny</b>
</pre>
<h3>Context and wantarray</h3>
<p>Something that often catches Perl beginners off guard is the concept of context. Calling an @array in scalar context will return the number of elements, and not the elements themselves. We can mimick this behavior with wantarray. This is how it works:</p>
<pre class="php" name="code">
#!/usr/bin/perl

use strict;

my @array1 = qw(a b c d e);
my @array2 = reverse_or_count(@array1);
my $count = reverse_or_count(@array1);

print "@array2n";
print "$count";

sub reverse_or_count(@){
	my @arr = @_;
	if (wantarray) {
		return reverse @arr;
	}
	else {
		return $#arr + 1; <b># last index of @arr plus 1</b>
	}
}
</pre>
<p>Thanks to the wantarray operator returns true if the subroutine is being called in an array context, and false if not. With that kind of control, the sky is the limit <img src='http://usestrict.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<h3>Closures</h3>
<p>Closures are usually thought of as very advanced topics, but they're not that bad at all. They're basically a way to work with lexical variables inside referenced subroutines. OK, I admit that that sounded terrible, but with a simple example we can clarify it.</p>
<pre class="php" name="code">
#!/usr/bin/perl

use strict;

sub make_counter() {
	my $start = shift;
	return sub { $start++ }
}

my $from_ten = make_counter(10);
my $from_three = make_counter(3);

print $from_ten-&gt;();    <b># 10</b>
print $from_ten-&gt;();    <b># 11</b>
print $from_three-&gt;();  <b># 3</b>
print $from_ten-&gt;();    <b># 12</b>
print $from_three-&gt;();  <b># 4</b>
</pre>
<p>This is how it works: Our sub make_counter takes the initial parameter into its own private $start variable and then returns an anonymous subroutine - the auto-incrementation of $start.  So when we call make_counter(10) we are actually creating a reference to the auto-increment with the initial value of 10. The beauty of it is that the value isn't lost when it comes out of scope. It's saved in memory for the next time it's called. That's why calling $from_ten-&gt;() will increment on top the latest result.</p>
<p>What is even nicer is that we can create as many instances of that subroutine reference as we want. Calling $from_three-&gt;() will not impact the results of $from_ten-&gt;().</p>
<p>That is pretty much all there is to it. Use your creativity to do the rest.</p>
<p>[ad#middle_end]</p>
<p style="text-align:right;">« Basic I/O | <a href="http://usestrict.net/2008/10/05/perl-crash-course/" target="_self">TOC</a> | File and directory tests and manipulation »</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/03/perl-crash-course-subroutines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl Crash Course: Gettin&#8217; jiggy wit it</title>
		<link>http://usestrict.net/2009/02/perl-crash-course-gettin-jiggy-wit-it/</link>
		<comments>http://usestrict.net/2009/02/perl-crash-course-gettin-jiggy-wit-it/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 18:27:26 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[newbies]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Course Howto]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=43</guid>
		<description><![CDATA[Built in Perl functions for Scalars, Arrays, and Hashes]]></description>
			<content:encoded><![CDATA[<p>So far we&#8217;ve seen how Perl&#8217;s basic data structures work and also how to put them all together. Now it&#8217;s time to see what built-in functions and techniques Perl provides us to work with scalars, arrays, and hashes.</p>
<p><strong>General functions</strong></p>
<p><em><strong>print [FILE HANDLE] list of data</strong></em></p>
<p>Used to print data. If not passed a FILE HANDLE, it will print directly to STDOUT. Interpolation rules apply. Some interesting details about <em>print</em> are:</p>
<pre class="brush:perl">

print @array;  # prints all elements of @array with
               # no spaces between them
print "@array";  # prints the elements WITH spaces between them
print $var1, $var2, @array;  # prints values with no spaces between them
print FH "some data";  # prints the string "some data" inside file represented by FH (see <em>open </em>below).
# Note the lack of comma between the FH and the data to be printed.
</pre>
<p><em><strong>open (FILE HANDLE, mode, filename)</strong></em> or  <em><strong>open (FILE HANDLE, &#8220;modefilename&#8221;)</strong></em></p>
<p>Opens a file or pipe for reading/writing/appending. Normally filehandles tend to be constants in uppercase, but it&#8217;s good practice to use variables to hold your filehandles. That way you can pass them between functions without occupying the main namespace. There are 2 styles of <tt>open</tt> &#8211; old style with 2 parameters and new style with 3.</p>
<p><span id="more-43"></span></p>
<p><em>open</em>&#8216;s modes are:<br />
&lt; (readonly),<br />
&gt; (create/write/truncate),<br />
&gt;&gt; (create/write/append),<br />
+&lt; (read/write/truncate),<br />
+&gt; (create/read/write/truncate),<br />
+&gt;&gt; (create/read/write/append)</p>
<pre class="brush:perl">

# old style - for reading
open (FH, "&lt;/path/to/somefile.txt") || die("Can't open file: $!n"); # $! returns the system error
# do something here
close(FH);

# new style - also for reading
open (my $fh, "&lt;", "/path/to/somefile.txt") || die("Can't open file: $!n");
# do something here
close($fh);</pre>
<p>When working with pipes, filenames begining with | indicate a pipe to write to. Filenames ending with | indicate filenames to read from. Use the special minus &#8216;-&#8217; sign to read from standard input.</p>
<p> <em><strong>printf($format_string,$value1[,$value2,$valueN])</strong></em> <tt>print</tt>&#8216;s older brother &#8211; takes patterns and prints a formatted string. It is extremely powerful and most people do not use it to its full extent.</p>
<p>  These are the formatting options you can use:</p>
<table style="border: 1px #000000 solid" border="0">
<tbody>
<tr>
<th style="border: 1px #000000 solid" align="left">Format</th>
<th style="border: 1px #000000 solid" align="left">Result</th>
</tr>
<tr>
<td style="border: 1px #000000 solid">%%</td>
<td style="border: 1px #000000 solid">A literal percent sign</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%c</td>
<td style="border: 1px #000000 solid">A character with the given ASCII code</td>
</tr>
<tr style="border: 1px #000000 solid">
<td style="border: 1px #000000 solid">%s</td>
<td style="border: 1px #000000 solid">A string</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%d</td>
<td style="border: 1px #000000 solid">A signed integer (decimal)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%u</td>
<td style="border: 1px #000000 solid">An unsigned integer (decimal)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%o</td>
<td style="border: 1px #000000 solid">An unsigned integer (octal)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%x</td>
<td style="border: 1px #000000 solid">An unsigned integer (hexadecimal)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%X</td>
<td style="border: 1px #000000 solid">An unsigned integer (hexadecimal using uppercase characters)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%e</td>
<td style="border: 1px #000000 solid">A floating point number (scientific notation)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%E</td>
<td style="border: 1px #000000 solid">A floating point number, uses E instead of e</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%f</td>
<td style="border: 1px #000000 solid">A floating point number (fixed decimal notation)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%g</td>
<td style="border: 1px #000000 solid">A floating point number (%e or %f notation according to value size)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%G</td>
<td style="border: 1px #000000 solid">A floating point number (as %g, but using .E. in place of .e. when<br />
appropriate)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%p</td>
<td style="border: 1px #000000 solid">A pointer (prints the memory address of the value in hexadecimal)</td>
</tr>
<tr>
<td style="border: 1px #000000 solid">%n</td>
<td style="border: 1px #000000 solid">Stores the number of characters output so far into the next variable in<br />
the parameter list</td>
</tr>
</tbody>
</table>
<p></p>
<pre class="brush:perl">

printf("Hello, My name is %s. Today is the %dth day of %s.", $name,$day,$month);
printf("This item costs $%.2f.",$some_number);  # escape the dollar sign
printf("I need 2 %%'s to get one printed with printf");
</pre>
<p><em><strong>sprintf</strong></em><em><strong>($format_string,$value1[,$value2,$valueN])</strong></em></p>
<p>Works the same as printf, but instead of printing the output, it returns the formatted string (allowing you to store it in a variable for later use).</p>
<pre class="brush:perl">

$string1 = sprintf("Hello, My name is %s. Today is the %dth day of %s.", $name,$day,$month);
$string2 = sprintf("This item costs $%.2f.",$some_number);  # escape the dollar sign
$string3 = sprintf("I need 2 %%'s to get one printed with printf");
</pre>
<p>[ad#middle_end]</p>
<p><em><strong>warn($message)</strong></em></p>
<p>Use <tt>warn</tt> to print messages into STRERR without exiting your script. Besides the regular usage of letting the user know when something goes bad (but not fatally so), I also find it handy to filter data from a given input file using <tt>print</tt> and <tt>warn</tt> along with shell redirectors (&gt;log.out and 2&gt;err.out). See the example below to better understand what I&#8217;m talking about.</p>
<pre class="brush:perl">

# in odd_even.pl
foreach my $i (0..10) { # .. = "to", so for $i == 0 to $i == 10
	if ($i % 2 == 0) { # Modulus (%)  operator, returns the remainder of a division
		print "$in"; # output to STDOUT
	}
	else {
		warn "$in"; # output to STDERR
	}
}

# in the command line
./odd_even.pl &gt; even.txt 2 &gt; odd.txt
</pre>
<p><em><strong>die($message)</strong></em></p>
<p>Print a message into STDERR and exit the script. If the message inside the <tt>die</tt> statement ends in a newline, only the message will be printed. If no newline is found, it will print additional information such as line number and script name.</p>
<pre class="brush:perl">

if ($some_fatal_error) {
	die("ACK!! Something went really badn"); # prints out "ACK!! Something went really bad"
}

if ($some_other_error){
	die("ACK!! Something went really bad"); # prints out "ACK!! Something went really bad at script.pl line someline"
}
</pre>
<p><strong>Scalar functions</strong></p>
<p><em><strong>split (/pattern/, $string [,number_of_elements])</strong></em><br />
<tt>split</tt> breaks a string at a given pattern into an arbitrary number of pieces. It returns a list which is usually assigned into an array for later use. Use an unescaped &#8216;|&#8217; (pipe) to split strings at each letter.</p>
<pre class="brush:perl">

$string = "Hello World";
@array = split /|/,$string; # same as @array = ('H','e','l','l','o',' ','W','o','r','l','d');

$string2 = "Name,Age,Street,Phone_number,Skills";
($name,$age,$rest) = split (/,/,$string2,3); # $name has 'Name', $age has 'Age', and $rest has 'Street,Phone_number,Skills'
</pre>
<p><em><strong>substr($string,offset[,length])</strong></em><br />
Returns a piece of a string starting from a given offset and having a given length. If the length is ommitted, it will return until the end of the string. Positive offsets count from left to right. Negative offsets count from right to left. It is also handy to get padding done on a string</p>
<pre class="brush:perl">

$string = "Hello World";
print substr($string,0); # Hello World
print substr($string,3,4); # lo W
print substr($string,-5); # World
print substr($string,-5,2); # Wo

$padding_template = "00000";

foreach my $i (10, 100, 1000, 10000) {

	print substr($padding_template . $i , (length($padding_template) * -1)), "n";
	# the line above will evaluate to the following stirng:
	# print substr(00000$i,-5),n; where $i will be 10, then 100, then 1000, then 10000

}

# results in
# 00010
# 00100
# 01000
# 10000
</pre>
<p><strong><em>chop($string)<br />
</em></strong>Used to cut off and return the last character of a string<strong><em>.</em></strong> The variable is altered automatically. <em>Note:</em> you cannot <em>chop</em> on a literal string. The value to be <em>chop</em>ped must reside in a variable. The reason for that is due to <tt>chop</tt> modifying the original string to hold the <tt>chop</tt>ped version. </p>
<pre class="brush:perl">

$string = "Hello World";
$chopped = chop($string);

print $string; # Hello Worl
print $chopped; # d
</pre>
<p><strong><em>chomp($string)</em></strong><br />
Similar to <em>chop</em>, however it will only remove the last character if and only if it is a newline (n). The same applies to not being able to <em>chomp</em> a literal string. See the shorthand example if you want to assign/<em>chomp</em> during the same command.</p>
<pre class="brush:perl">

$string = "Hello World";
chomp($string); # no change, since there's no n at the end of $string

chomp($string2 = "with newline n"); # shorthand version
print $string2, $string; # with newlineHello World
</pre>
<p><strong><em>pack</em></strong> and <strong><em>unpack</em></strong><br />
A couple of the most powerful string manipulation functions (inherited from C), it&#8217;s so complex that I recommend that you read <a href="http://perldoc.perl.org/functions/pack.html">this</a> to see how it works.</p>
<p><strong>Array functions</strong></p>
<p><strong><em>join</em></strong><br />
Opposite of <tt>split</tt>. Takes an array and <tt>join</tt>s its values into a string using nothing, a given character, or a string as field separator. I find it handy to create large SQL queries with it. (See example below).</p>
<pre class="brush:perl">

@array = qw(Red Green Blue Black); # qw() puts double quotes around each word separated by space
$string = join(',',@array); # $string is "Red,Green,Blue,Black"
</pre>
<p><strong><em>shift</em></strong> and <strong><em>unshift</em></strong><br />
Use shift to remove and assign the first element of an array, and unshift to do the opposite. Shift is mostly used inside subroutines to get elements from the special @_ array (@_ contains all parameters passed onto a subroutine).</p>
<pre class="brush:perl">
@colors = qw(Red Green Blue Black);

$color = shift @colors; # or shift(@colors);
print "@colors";  # Green Blue Black;
print $color; # Red

unshift(@colors,$color);
print "@colors"; # Red Green Blue Black
</pre>
<p><strong><em>pop</em></strong> and <strong><em>push</em></strong><br />
Similarly to <tt>shift</tt> and <tt>unshift</tt>, <tt>pop</tt> and <tt>push</tt> work on the right site of an array.</p>
<pre class="brush:perl">

@pets = qw(Cat Dog Bird Fish);
$mypet = pop @pets;
print $mypet; # Fish
print "@pets"; # Cat Dog Bird

push(@pets,$mypet);
print "@pets"; # Cat Dog Bird Fish
</pre>
<p><strong><em>array slices</em></strong><br />
Not a function, but a syntax structure which allows you to access subsets of an array. Keep in mind Perl&#8217;s singular/plural constructs (using @ instead of $) while using a list, array, or range as your index.</p>
<pre class="brush:perl">

@pets = qw(Cat Dog Bird Fish);
print $pets[0]; # Cat - NOT a slice
print @pets[0,1,2]; # CatDogBird
print @pets[0..2]; # same thing
print @pets[qw(0 1 2)]; # same thing
</pre>
<p><strong>Hash functions</strong></p>
<p><strong><em>each</em></strong><br />
<tt>each</tt> iterates through the key/value pairs of a hash, returning them in a list context.</p>
<pre class="brush:perl">

while(($key,$value) = each (%hash)) {

	print $key, " =&gt; ", $value, "n"; 

}

# Prints
# key1 =&gt; val1
# key2 =&gt; val2
</pre>
<p><strong><em>exists</em></strong><br />
Checks for the existence of a key in a hash. Will return true even if the key&#8217;s value is false (undefined, empty string, zero, etc.).</p>
<pre class="brush:perl">

%hash = (key1 => undef,
         key2 => 'val2');

print "Got it!!" if exists($hash{key1}); # returns Got it!!
</pre>
<p><strong><em>delete</em></strong><br />
Removes a key/value pair from a hash. Use it when you want <tt>exists</tt> to return false.</p>
<pre class="brush:perl">
delete($hash{key1});

print "Got it!!" if exists $hash{key1}; # does not print anything
</pre>
<p>[ad#middle_end]</p>
<p style="text-align:right;"><a href="http://usestrict.net/2008/11/20/perl-crash-course-references-and-complex-data-structures-cds/" target="_self">« References and Complex Data Structures (CDS)</a> | <a href="http://usestrict.net/2008/10/05/perl-crash-course/" target="_self">TOC</a> | <a href="http://usestrict.net/2009/04/07/perl-crash-course-basic-regular-expressions/">Basic Regular Expressions »</a></p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/02/perl-crash-course-gettin-jiggy-wit-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl: Installing MQSeries CPAN module on Windows XP</title>
		<link>http://usestrict.net/2009/01/perl-installing-mqseries-module-on-windows-xp/</link>
		<comments>http://usestrict.net/2009/01/perl-installing-mqseries-module-on-windows-xp/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 13:35:34 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[MQseries]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[c program]]></category>
		<category><![CDATA[chars]]></category>
		<category><![CDATA[cmd]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[cpan module]]></category>
		<category><![CDATA[crimson editor]]></category>
		<category><![CDATA[environment variables]]></category>
		<category><![CDATA[file names]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[ibm websphere mq]]></category>
		<category><![CDATA[Install]]></category>
		<category><![CDATA[lib directory]]></category>
		<category><![CDATA[microsoft visual c]]></category>
		<category><![CDATA[microsoft visual studio]]></category>
		<category><![CDATA[MS Visual Studio]]></category>
		<category><![CDATA[new computer]]></category>
		<category><![CDATA[notepad]]></category>
		<category><![CDATA[parse]]></category>
		<category><![CDATA[piece of cake]]></category>
		<category><![CDATA[right tools]]></category>
		<category><![CDATA[step 3]]></category>
		<category><![CDATA[studio 9]]></category>
		<category><![CDATA[trial version]]></category>
		<category><![CDATA[visual studio tools]]></category>
		<category><![CDATA[Windows XP]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=212</guid>
		<description><![CDATA[How to easily install CPAN's MQSeries under Windows XP.]]></description>
			<content:encoded><![CDATA[<p>Installing MQSeries module on Windows XP is a piece of cake, as long as you get the right tools before you even try.</p>
<p><strong>Update: July 2, 2009</strong> I had to install the module on a new computer running Windows XP and it looks like I had missed a few steps in the original how-to below. It&#8217;s been updated with the manual editing steps. From step 3 down, it&#8217;s all new.</p>
<p><strong>This is what you need:</strong></p>
<ol>
<li>MQSeries installed (get the 90-day trial version <a href="http://www.ibm.com/developerworks/downloads/ws/wmq/" target="_blank">here</a>. You will need to register, but there&#8217;s no charge for that)</li>
<li>Microsoft Visual C++ (it&#8217;s free, and you can get it <a href="http://www.microsoft.com/express/download/default.aspx" target="_blank">here</a>)</li>
<li>Perl (I use <a href="http://www.activestate.com" target="_blank">ActiveState</a>)</li>
</ol>
<p><strong>Steps to get it installed:</strong></p>
<ol>
<li>Open a command prompt (Start-&gt;Run-&gt;cmd.exe)</li>
<li><strong>(Extremely important!!)</strong>Set up your build environment by running <strong><em>vcvarsall.bat</em></strong>. Mine is under <strong><em>C:Program FilesMicrosoft Visual Studio 9.0VC<br />
</em></strong>An alternative to this step is to open a <strong>Visual Studio 2008 Command Prompt</strong> (Start-&gt;All Programs-&gt;Microsoft C++ 2008 Express Edition-&gt;Visual Studio Tools-&gt;Visual Studio 2008 Command Prompt)</li>
<li>Make sure your environment variables are set with MQ data: INCLUDE=pathtotoolscinclude directory, LIB=pathtotoolslib directory (typing <code>set</code> will show you your env vars)</li>
<li>Install pre-requisite Params::Validate by running <em><strong>perl -MCPAN -e &#8220;install Params::Validate&#8221;</strong></em>
<li>Download MQSeries manually by running <em><strong>perl -MCPAN -e &#8220;get MQSeries&#8221;</strong></em></li>
<li>cd into the directory where you have your cpan (mine is c:Perlcpanbuild) and enter MQSeries-x.xx-* (where * is a series of random chars if you&#8217;re using the latest CPAN)</li>
<li>With a decent text editor (I&#8217;m using Notepad++ and also like Crimson Editor and Programmer&#8217;s Notepad 2), edit CONFIG file: uncomment MQMTOP = &#8230; and replace the path with the path to your MQ Tools directory. It&#8217;s OK to use long directory and file names (e.g c:Program FilesIBMWebsphere MQTools)
<li>Now cd into the <strong>utils</strong> directory, open <strong>parse_headers</strong> file and comment out or delete the line near the top where it says &#8220;my $include = &#8216;/opt/mqm/inc&#8217;;&#8221;. The reason for this is that <strong>my</strong> overwrites the <strong>$include</strong> variable previously populated by <strong>parse_config</strong> file.
<li>Save your changes and in the base directory for the MQSeries build, run <strong>perl Makefile.PL</strong>. It might complain about some libs not being found, but that wasn&#8217;t a show stopper for me.
<li>Run <strong>nmake</strong>. It came with your MS Visual C++ install and should be in your PATH.
<li>Run <strong>nmake test</strong>. It&#8217;ll fail, since you didn&#8217;t set any valid data in the CONFIG file. If you have any valid data such as QM and Queues to test it with, go ahead and set them in the CONFIG file and run <strong>nmake test</strong> again. If not, that&#8217;s OK.
<li>If <strong>nmake test</strong> was the only place where it failed, then you&#8217;re good to run <strong>nmake install</strong>.
</ol>
<p>That&#8217;s it &#8211; Perl MQSeries module should now be installed.</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/01/perl-installing-mqseries-module-on-windows-xp/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Perl: Connecting to an Oracle database WITHOUT having an installed client</title>
		<link>http://usestrict.net/2009/01/perl-connecting-to-an-oracle-database-without-having-an-installed-client/</link>
		<comments>http://usestrict.net/2009/01/perl-connecting-to-an-oracle-database-without-having-an-installed-client/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 03:41:28 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[alternative]]></category>
		<category><![CDATA[archive tool]]></category>
		<category><![CDATA[array reference]]></category>
		<category><![CDATA[bastard]]></category>
		<category><![CDATA[BEGIN]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[CPAN]]></category>
		<category><![CDATA[day]]></category>
		<category><![CDATA[dbd::oracle]]></category>
		<category><![CDATA[dbi]]></category>
		<category><![CDATA[dbs]]></category>
		<category><![CDATA[ENV]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[fileName]]></category>
		<category><![CDATA[filenames]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[hostname]]></category>
		<category><![CDATA[intention]]></category>
		<category><![CDATA[ip port]]></category>
		<category><![CDATA[lazy bastard]]></category>
		<category><![CDATA[libs]]></category>
		<category><![CDATA[oracle 10g client]]></category>
		<category><![CDATA[oracle client]]></category>
		<category><![CDATA[oracle database]]></category>
		<category><![CDATA[PAR]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[perl archive]]></category>
		<category><![CDATA[perl module]]></category>
		<category><![CDATA[Pretty]]></category>
		<category><![CDATA[quickie]]></category>
		<category><![CDATA[Solaris]]></category>
		<category><![CDATA[subroutine]]></category>
		<category><![CDATA[SUM]]></category>
		<category><![CDATA[sun solaris sparc]]></category>
		<category><![CDATA[target machines]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[Unpack]]></category>
		<category><![CDATA[username]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=154</guid>
		<description><![CDATA[Using Perl to connect to a DB without having Oracle Client installed.]]></description>
			<content:encoded><![CDATA[<p>I started this post with the intention of having it be a quickie, just showing people how to connect to Oracle with Perl/DBI without having to have Oracle client or even Perl installed, but it&#8217;s not that simple.  So I decided to rewrite it with detailed instructions.</p>
<p>Here is a list of what I used:</p>
<p><strong>Machine:</strong> Sun Solaris SPARC on build and target machines<br />
<strong>Oracle:</strong> Oracle 10g client (build machine only)<br />
<strong>Perl:</strong> v. 5.10.0 (build machine only)<br />
<strong>Perl modules:</strong> <a href="http://search.cpan.org/~timb/DBI-1.607/DBI.pm" target="_blank">DBI (1.607)</a>, <a href="http://search.cpan.org/~pythian/DBD-Oracle-1.22/Oracle.pm" target="_blank">DBD::Oracle (1.22)</a>, <a href="http://search.cpan.org/~smueller/PAR-1.002/lib/PAR.pm" target="_blank">PAR (0.983)</a>, <a href="http://search.cpan.org/~rschupp/PAR-Packer-1.012/lib/pp.pm" target="_blank">pp (0.982)</a>, <a href="http://search.cpan.org/~nwclark/perl-5.8.9/lib/PerlIO.pm">PerlIO (1.04)</a> (build machine only)</p>
<p><span id="more-154"></span></p>
<p>&nbsp;</p>
<h2>How I did it:</h2>
<p>Being the <a href="http://wiki.preshweb.co.uk/doku.php?id=perl:virtues" target="_blank">lazy</a> bastard that I am, I decided to write a Perl module that would do my DBI connections for me once I supplied it the SID, username, and password. This module isn&#8217;t in CPAN, but you can probably find similar ones in there. Who knows maybe one day I&#8217;ll make it available to the public, but for now I will only explain how it works and show the tidbits I used to get it connecting without the Oracle client installed. Let&#8217;s call my module <strong>MyDB.pm</strong> (at the time of this writing, there is no MyDB.pm module in CPAN).</p>
<p><strong>MyDB.pm:</strong> exports one subroutine: <strong>connect()</strong>. <strong> connect()</strong> takes an array reference of 3 values: <em>SID</em>, <em>username</em>, <em>password</em>. It then uses the given SID to check against <strong>%configured_dbs</strong> and fetch hostname/IP,  port, and alternative SID. It then connects to the DBI. Pretty straight-forward.</p>
<p><strong>Oracle Client: </strong>You&#8217;ll need the Oracle Client installed in your build machine. Or not. As long as you have access to the following files (the example here is for 10.1 version &#8211; your filenames may vary): <strong>libclntsh.so.10.1</strong>, and <strong>libnnz10.so</strong>. These are the magic libs that we will carry along with us.</p>
<p><strong>PAR/pp:</strong> The Perl Archive Tool is a VERY handy module. It basically allows you to pack modules/files into a regular zip (renamed to .par) and even to create self extracting executables. It comes with tools such as parl to load those packages and deploy the scripts inside, or you can run it from inside a separate script to use your modules without having to install them in a specific path. Oh, and with the PAR self extracting executable, you can even bundle Perl core files and run it in a machine that doesn&#8217;t have Perl installed! Sweet, eh? pp is part of the PAR family &#8211; it&#8217;s thescript that does the creation of the par packages. One downside of PAR is that it creates potentially HUGE  packages. A simple hello world can be over 2Mb large. But that&#8217;s not a concern in this tutorial, since we will be getting rid of having to keep Oracle up to date in every single machine, changing environment variables and the such.</p>
<p>When running a PAR package, it calculates the MD5SUM of the file and creates a temporary directory under /var/tmp/par-<em>userId</em>/cache-<em>md5sum </em>(replace <em>userId</em> with the ID of the person running the file, and <em>md5sum</em> with the actual md5sum) . It then unpacks the contents of the PAR into that directory and sets some environment variables &#8211; some of which will tell Perl to check in there for modules.  However, it seems to not automatically extract the libs, so we have to modify MyDB.pm to have it behave appropriately.</p>
<h1><img class="alignnone size-full wp-image-8" title="spacer" src="http://usestrict.net/wp-content/uploads/2008/10/spacer1.gif" alt="spacer" width="10" height="20" /></h1>
<h2>Making MyDB.pm work when called in a PAR context</h2>
<p>Create a BEGIN block checking for <strong>$ENV{PAR_TEMP}</strong>. This is the value of the PAR temp directory where the files should be extracted. Since PAR creates zipped files, it offers a method to return an Archive::Zip  handler:</p>
<p style="padding-left: 60px;"><em>my $zip_handler = PAR::par_handle(&#8216;MyDB.par&#8217;)</em>;</p>
<p>Now you can use Archive::Zip methods to manipulate your .par file. I used the following code for my BEGIN block:</p>
<pre class="brush:perl">BEGIN {
	if ($ENV{PAR_TEMP}) {

		# Get $par_cache (easier to type than $ENV{PAR_TEMP})
		my $par_cache = $ENV{PAR_TEMP};

		# Get Zip handler
		my $par_file = PAR::handle("MyDB.par");

		# Set files to look for
		my %membersToFind = (’libclntsh.so.10.1’ =&gt;1,
							 ’libnnz10.so’ =&gt; 1 );

		# Unpack files
		for my $m ($par_file-&gt;members()) {

			# Get path/name of the zipped file
			my $fileName = $m-&gt;fileName();

			# Prepare to check if the libs
			# have already been extracted
			use Find::File;

			# Iterate through %membersToFind keys
			for my $k (keys %membersToFind) {

				# If zipped file is one of the keys...
				if ($fileName =~ /$k/) {

					# do nothing if the file has already been extracted
					next if find(sub { /$k/ or return 0 },$par_cache); 

					# ...then remove from hash (we’ll check the hash later)...
					delete $membersToFind{$k};

					# ... and unpack into $par_cache directory
					$par_file-&gt;extractMember($fileName,"$par_cache") ||
					warn ("Failed to extract $fileName n");

				}
			}
		}

		# Check to see if any of the files wasn’t unpacked because it wasn’t found
		if (scalar(keys %membersToFind) &gt; 0) {

			warn("The following file(s) could not be found in PAR file: " .  join(’,’,@{ keys %membersToFind }) ."n");

		}
	}
}</pre>
<p>So now MyDB.pm will know what to do if $ENV{PAR_TEMP} is set.  The next step is to generate the PAR file.</p>
<h1><img class="alignnone size-full wp-image-8" title="spacer" src="http://usestrict.net/wp-content/uploads/2008/10/spacer1.gif" alt="spacer" width="10" height="20" /></h1>
<h2>Creating the PAR package</h2>
<p>You&#8217;ll need a dummy perl script to pass to <strong>pp</strong>:</p>
<pre class="brush:shell">	$ echo "use MyDB;" &gt; dummy.pl</pre>
<p>and then create the PAR file. Make sure MyDB.pm and your oracle libs are in places where Perl can find it. I placed MyDB.pm in the same directory as dummy.pl, and set LD_LIBRARY_PATH to my $ORACLE_HOME/lib32 (if you&#8217;re using Instant Client, set it to $ORACLE_HOME/instantclient or wherever your instant client keeps the libs). The pp command is this (on a shell prompt):</p>
<pre class="brush:shell">
$ pp -z 9 -v 3 -p -d -o MyDB.par
	-X DBD::Proxy
	-X DBD::DBM
	-X DBD::File
	-X DBD::NullP
	-X DBD::Gofer
	-X DBD::Sponge
	-X DBD::ExampleP
	-X DBD::mysql
	-X DBD::Gofer::Policy::rush
	-X DBD::Gofer::Policy::classic
	-X DBD::Gofer::Policy::Base
	-X DBD::Gofer::Policy::pedantic
	-X DBD::Gofer::Transport::pipeone
	-X DBD::Gofer::Transport::Base
	-X DBD::Gofer::Transport::stream
	-X DBD::Gofer::Transport::null
	-X DBD::mysql::GetInfo
	-X DBD::Chart
	-X DBD::Chart::Plot
	-M MyDB
	-M PerlIO
	-l libclntsh.so.10.1
	-l libnnz10.so
        -l libociei.so   # for Oracle instant client users only! Thanks to Jonathon Robinson for the heads up. (see comments for details)
	dummy.pl</pre>
<p><strong>pp command explained</strong></p>
<p><strong>pp:</strong> the PAR packer script<br />
<strong>-z 9:</strong> maximum compression<br />
<strong>-v 3:</strong> maximum verbosity<br />
<strong>-p:</strong> create par file<br />
<strong>-d:</strong> dependent. This means it will not add the Perl interpreter to the bundle. This reduces its size, but makes it rely on either perl being installed in the target machine, or your script (the one that&#8217;s going to use MyDB) being PAR&#8217;d without the -d option.<br />
<strong>-0 MyDB.par:</strong> the filename to be used on output<br />
<strong>-X <em>module</em>:</strong> removes un-necessary modules. Read more about it <a href="http://search.cpan.org/~smueller/PAR-1.002/lib/PAR/FAQ.pod#The_resulting_files_are_huge!_How_can_I_reduce_the_size_of_the_output_file?" target="_blank">here</a>.<br />
<strong>-M <em>module</em>:</strong> the modules you want to add (PAR sometimes misses a module during its dependency scan).  PerlIO is required.<br />
<strong>-l <em>lib</em>:</strong> adds the additional libs<strong><br />
dummy.pl:</strong> last item of the command, tells <strong>pp</strong> what the main script is.<br />
There &#8211; after lots of output on the screen, you should have a pretty large MyDB.par (at least 7Mb). Now we have to alter our main script (the one that <em>use</em>s MyDB in the first place) to have it handle the PAR file. Add the following lines right after your <em>use strict;</em> line (you DO use strict, RIGHT?!).</p>
<pre class="brush:perl">
          use PAR './MyDB.par';
          use MyDB;
          # the rest is business as usual
</pre>
<p>Once altered, you can choose to <strong>pp</strong> your script to have it run without a perl interpreter on another machine. This might take several attempts, since you will have to test the executable a few times to make sure you got all your modules bundled. The basic pp command though is this:</p>
<pre class="brush:shell">
       $ pp -z 9 -v 3 -o yourscript.exe yourscript.pl    # .exe not required
</pre>
<p>Here the absense of -d makes it assume -B which bundles Perl inside the executable. As mentioned before, you might need to add some -M <em>module</em> parameters before yourscript.pl to catch any missing modules.</p>
<h2>Running the scripts</h2>
<p>To run the scripts, just send them to the target machine and execute <em>yourscript.exe</em>. It will fetch MyDB.par in the same directory, extract it to $ENV{PAR_TEMP} the first time (so it might be a little slow at first) and carry on with its logic.</p>
<h2>Caveat</h2>
<p>I strongly advise that you delete your par_cache directory between rebuilds (while testing). The reason for this is that the cache will be created by the execution of <em>yourscript.exe</em> and NOT by MyDB.par. When this happens and you alter MyDB.par, the changes will not be reflected when you run <em>yourscript.exe</em>.</p>
<p>If you liked this post, please leave a comment. If you didn&#8217;t, leave a comment too! <img src='http://usestrict.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I&#8217;d like to know what people think of my blog and ways to improve it.</p>
<p>&nbsp;</p>
<h3>Book Suggestions:</h3>
<div>
<script type="text/javascript">
    (function(){
        document.write('<script type="text/javascript" src="http://cb1.cronblocks.com//js/content.js?c=11&#038;t='+(Math.floor(new Date().getTime()/1000))+'&#038;s=client"><\/script>');
    })();
</script>
</div>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/01/perl-connecting-to-an-oracle-database-without-having-an-installed-client/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

