<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Recursion with Perl and CDS</title>
	<atom:link href="http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/feed/" rel="self" type="application/rss+xml" />
	<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/</link>
	<description>Vinny&#039;s Technical Corner</description>
	<lastBuildDate>Wed, 30 Jun 2010 09:38:36 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
	<item>
		<title>By: Vinny</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-454</link>
		<dc:creator>Vinny</dc:creator>
		<pubDate>Sat, 11 Jul 2009 14:57:49 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-454</guid>
		<description>Not really - I want to be able to use it with scalars, hashes, and arrays.</description>
		<content:encoded><![CDATA[<p>Not really &#8211; I want to be able to use it with scalars, hashes, and arrays.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alex</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-450</link>
		<dc:creator>Alex</dc:creator>
		<pubDate>Sat, 11 Jul 2009 04:43:42 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-450</guid>
		<description>Just try as is. You will see result.
As I see from your requirement you are pushing basically scalars to the function.</description>
		<content:encoded><![CDATA[<p>Just try as is. You will see result.<br />
As I see from your requirement you are pushing basically scalars to the function.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vinny</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-312</link>
		<dc:creator>Vinny</dc:creator>
		<pubDate>Fri, 26 Jun 2009 13:48:02 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-312</guid>
		<description>Alex,

By calling &lt;code&gt;trim()&lt;/code&gt; as &lt;code&gt;&amp;trim()&lt;/code&gt;, you&#039;re bypassing protocols altogether. Try removing all the &lt;em&gt;&amp;&lt;/em&gt; from your calls and you&#039;ll see that nothing gets trimmed. Also, supposing it did work, you would be limiting the use of any data structures other than scalars.</description>
		<content:encoded><![CDATA[<p>Alex,</p>
<p>By calling <code>trim()</code> as <code>&#038;trim()</code>, you&#8217;re bypassing protocols altogether. Try removing all the <em>&amp;</em> from your calls and you&#8217;ll see that nothing gets trimmed. Also, supposing it did work, you would be limiting the use of any data structures other than scalars.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: AlexB...</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-300</link>
		<dc:creator>AlexB...</dc:creator>
		<pubDate>Wed, 24 Jun 2009 22:44:47 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-300</guid>
		<description>Vinny, I understand your code is working and working directly at reference.
When I did modification I mean it is also working as prototype, no errors accrues. It is working with hashes and arrays without problem. 
&lt;code&gt;
sub trim(\$);
&amp;trim($data);
&lt;/code&gt;
&lt;code&gt;
sub trim(\$) {
    my $input = shift;
    if (ref($input) eq &quot;ARRAY&quot;) {
        for my $key (0..$#{$input}) {
            ${$input}[$key] = &amp;trim(${$input}[$key]);
        }
    } elsif (ref($input) eq &quot;HASH&quot;) {
        foreach my $key (keys %{$input}) {
            ${$input}{$key} = &amp;trim(${$input}{$key});
        }
    } else {
        $input =~ s%(^\s+&#124;\s+$)%%g;
    }
    return $input;
}
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Vinny, I understand your code is working and working directly at reference.<br />
When I did modification I mean it is also working as prototype, no errors accrues. It is working with hashes and arrays without problem.<br />
<code><br />
sub trim(\$);<br />
&amp;trim($data);<br />
</code><br />
<code><br />
sub trim(\$) {<br />
    my $input = shift;<br />
    if (ref($input) eq "ARRAY") {<br />
        for my $key (0..$#{$input}) {<br />
            ${$input}[$key] = &amp;trim(${$input}[$key]);<br />
        }<br />
    } elsif (ref($input) eq "HASH") {<br />
        foreach my $key (keys %{$input}) {<br />
            ${$input}{$key} = &amp;trim(${$input}{$key});<br />
        }<br />
    } else {<br />
        $input =~ s%(^\s+|\s+$)%%g;<br />
    }<br />
    return $input;<br />
}<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vinny</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-295</link>
		<dc:creator>Vinny</dc:creator>
		<pubDate>Wed, 24 Jun 2009 12:14:04 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-295</guid>
		<description>Hi AlexB, 

Let me comment on your code. It has to do with what Christine Morton commented on and I explained on that reply about passing variables by value and by reference. 

My original subroutine works. It runs a loop on each element of &lt;code&gt;@_&lt;/code&gt; handling them as references to the original input parameter.  That&#039;s why you &lt;strong&gt;don&#039;t&lt;/strong&gt;  see &lt;code&gt;shift()&lt;/code&gt; in my subroutine. When you call &lt;code&gt;shift()&lt;/code&gt; like you did on yours, you&#039;re no longer working on references but on copies of the values. Yes, when you&#039;re working on copies the originals don&#039;t get changed, so you have to return the modified data and assign it to the original like you did for it to work, but I didn&#039;t really want that - I wanted it to work like &lt;code&gt;push()&lt;/code&gt;, auto-increment/decrement and many other Perl unary functions (no lvalue!). 

Your code works - but it&#039;s a different approach (the one Christine Morton was asking about).

Cheers,
Vinny</description>
		<content:encoded><![CDATA[<p>Hi AlexB, </p>
<p>Let me comment on your code. It has to do with what Christine Morton commented on and I explained on that reply about passing variables by value and by reference. </p>
<p>My original subroutine works. It runs a loop on each element of <code>@_</code> handling them as references to the original input parameter.  That&#8217;s why you <strong>don&#8217;t</strong>  see <code>shift()</code> in my subroutine. When you call <code>shift()</code> like you did on yours, you&#8217;re no longer working on references but on copies of the values. Yes, when you&#8217;re working on copies the originals don&#8217;t get changed, so you have to return the modified data and assign it to the original like you did for it to work, but I didn&#8217;t really want that &#8211; I wanted it to work like <code>push()</code>, auto-increment/decrement and many other Perl unary functions (no lvalue!). </p>
<p>Your code works &#8211; but it&#8217;s a different approach (the one Christine Morton was asking about).</p>
<p>Cheers,<br />
Vinny</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: AlexB...</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-286</link>
		<dc:creator>AlexB...</dc:creator>
		<pubDate>Wed, 24 Jun 2009 04:56:11 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-286</guid>
		<description>Well, I did small modification to make it works. Anyway, you are talking about references at &lt;code&gt;trim&lt;/code&gt; sub. When sub will get reference it is just one or could be list as you want. I did test just in one reference in following codes.

First test code:
&lt;code&gt;
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $data = [
                   {
                      key1 =&gt; &#039;   trim me!   &#039;,
                      key2 =&gt; &#039;   trim me too!    &#039;,
                   },
                   [
                      &#039;some element to trim   &#039;,
                      &#039;    another one    &#039;,
                   ],
                   &#039;    a simple string needing trimming    &#039;,
              ];

&amp;trim($data);
print &quot;result : &quot;.Dumper($data);

sub trim {
    my $input = shift;
    if (ref($input) eq &quot;ARRAY&quot;) {
        print &quot;ARRAY:&quot;.Dumper($input);
        foreach my $element (@{$input}) {
            &amp;trim($element);
        }
    } elsif (ref($input) eq &quot;HASH&quot;) {
        print &quot;HASH:&quot;.Dumper($input);
        foreach my $element (values %{$input}) {
            &amp;trim($element);
        }
    } else {
        $input =~ s%(^\s+&#124;\s+$)%%g;
        print &quot;STRING:\&#039;&quot;.$input.&quot;\&#039;\n&quot;;
    }
}
__END__
&lt;/code&gt;

As we see, each value for each nested element have been processed properly, but not modified at original source.
&lt;em&gt;
ARRAY:$VAR1 = [
          {
            &#039;key2&#039; =&gt; &#039;   trim me too!    &#039;,
            &#039;key1&#039; =&gt; &#039;   trim me!   &#039;
          },
          [
            &#039;some element to trim   &#039;,
            &#039;    another one    &#039;
          ],
          &#039;    a simple string needing trimming    &#039;
        ];
HASH:$VAR1 = {
          &#039;key2&#039; =&gt; &#039;   trim me too!    &#039;,
          &#039;key1&#039; =&gt; &#039;   trim me!   &#039;
        };
STRING:&#039;trim me too!&#039;
STRING:&#039;trim me!&#039;
ARRAY:$VAR1 = [
          &#039;some element to trim   &#039;,
          &#039;    another one    &#039;
        ];
STRING:&#039;some element to trim&#039;
STRING:&#039;another one&#039;
STRING:&#039;a simple string needing trimming&#039;
result : $VAR1 = [
          {
            &#039;key2&#039; =&gt; &#039;   trim me too!    &#039;,
            &#039;key1&#039; =&gt; &#039;   trim me!   &#039;
          },
          [
            &#039;some element to trim   &#039;,
            &#039;    another one    &#039;
          ],
          &#039;    a simple string needing trimming    &#039;
        ];
&lt;/em&gt;

It is expected result in this case. When we will do other small code modification to set processed data it is returns desirable result.

Second test code:
&lt;code&gt;
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $data = [
                   {
                      key1 =&gt; &#039;   trim me!   &#039;,
                      key2 =&gt; &#039;   trim me too!    &#039;,
                   },
                   [
                      &#039;some element to trim   &#039;,
                      &#039;    another one    &#039;,
                   ],
                   &#039;    a simple string needing trimming    &#039;,
              ];

&amp;trim($data);
print &quot;result : &quot;.Dumper($data);

sub trim {
    my $input = shift;
    if (ref($input) eq &quot;ARRAY&quot;) {
        for (my $key=0; $key&lt;scalar(@{$input}); $key++) {
            ${$input}[$key] = &amp;trim(${$input}[$key]);
        }
    } elsif (ref($input) eq &quot;HASH&quot;) {
        foreach my $key (keys %{$input}) {
            ${$input}{$key} = &amp;trim(${$input}{$key});
        }
    } else {
        $input =~ s%(^\s+&#124;\s+$)%%g;
    }
    return $input;
}
__END__
&lt;/code&gt;

This is output:
&lt;code&gt;
result : $VAR1 = [
          {
            &#039;key2&#039; =&gt; &#039;trim me too!&#039;,
            &#039;key1&#039; =&gt; &#039;trim me!&#039;
          },
          [
            &#039;some element to trim&#039;,
            &#039;another one&#039;
          ],
          &#039;a simple string needing trimming&#039;
        ];
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Well, I did small modification to make it works. Anyway, you are talking about references at <code>trim</code> sub. When sub will get reference it is just one or could be list as you want. I did test just in one reference in following codes.</p>
<p>First test code:<br />
<code><br />
#!/usr/bin/perl -w<br />
use strict;<br />
use Data::Dumper;<br />
my $data = [<br />
                   {<br />
                      key1 =&gt; '   trim me!   ',<br />
                      key2 =&gt; '   trim me too!    ',<br />
                   },<br />
                   [<br />
                      'some element to trim   ',<br />
                      '    another one    ',<br />
                   ],<br />
                   '    a simple string needing trimming    ',<br />
              ];</p>
<p>&amp;trim($data);<br />
print "result : ".Dumper($data);</p>
<p>sub trim {<br />
    my $input = shift;<br />
    if (ref($input) eq "ARRAY") {<br />
        print "ARRAY:".Dumper($input);<br />
        foreach my $element (@{$input}) {<br />
            &amp;trim($element);<br />
        }<br />
    } elsif (ref($input) eq "HASH") {<br />
        print "HASH:".Dumper($input);<br />
        foreach my $element (values %{$input}) {<br />
            &amp;trim($element);<br />
        }<br />
    } else {<br />
        $input =~ s%(^\s+|\s+$)%%g;<br />
        print "STRING:\'".$input."\'\n";<br />
    }<br />
}<br />
__END__<br />
</code></p>
<p>As we see, each value for each nested element have been processed properly, but not modified at original source.<br />
<em><br />
ARRAY:$VAR1 = [<br />
          {<br />
            'key2' =&gt; '   trim me too!    ',<br />
            'key1' =&gt; '   trim me!   '<br />
          },<br />
          [<br />
            'some element to trim   ',<br />
            '    another one    '<br />
          ],<br />
          &#8216;    a simple string needing trimming    &#8216;<br />
        ];<br />
HASH:$VAR1 = {<br />
          &#8216;key2&#8242; =&gt; &#8216;   trim me too!    &#8216;,<br />
          &#8216;key1&#8242; =&gt; &#8216;   trim me!   &#8216;<br />
        };<br />
STRING:&#8217;trim me too!&#8217;<br />
STRING:&#8217;trim me!&#8217;<br />
ARRAY:$VAR1 = [<br />
          'some element to trim   ',<br />
          '    another one    '<br />
        ];<br />
STRING:&#8217;some element to trim&#8217;<br />
STRING:&#8217;another one&#8217;<br />
STRING:&#8217;a simple string needing trimming&#8217;<br />
result : $VAR1 = [<br />
          {<br />
            'key2' =&gt; '   trim me too!    ',<br />
            'key1' =&gt; '   trim me!   '<br />
          },<br />
          [<br />
            'some element to trim   ',<br />
            '    another one    '<br />
          ],<br />
          &#8216;    a simple string needing trimming    &#8216;<br />
        ];<br />
</em></p>
<p>It is expected result in this case. When we will do other small code modification to set processed data it is returns desirable result.</p>
<p>Second test code:<br />
<code><br />
#!/usr/bin/perl -w<br />
use strict;<br />
use Data::Dumper;<br />
my $data = [<br />
                   {<br />
                      key1 =&gt; '   trim me!   ',<br />
                      key2 =&gt; '   trim me too!    ',<br />
                   },<br />
                   [<br />
                      'some element to trim   ',<br />
                      '    another one    ',<br />
                   ],<br />
                   '    a simple string needing trimming    ',<br />
              ];</p>
<p>&amp;trim($data);<br />
print "result : ".Dumper($data);</p>
<p>sub trim {<br />
    my $input = shift;<br />
    if (ref($input) eq "ARRAY") {<br />
        for (my $key=0; $key&lt;scalar(@{$input}); $key++) {<br />
            ${$input}[$key] = &amp;trim(${$input}[$key]);<br />
        }<br />
    } elsif (ref($input) eq "HASH") {<br />
        foreach my $key (keys %{$input}) {<br />
            ${$input}{$key} = &amp;trim(${$input}{$key});<br />
        }<br />
    } else {<br />
        $input =~ s%(^\s+|\s+$)%%g;<br />
    }<br />
    return $input;<br />
}<br />
__END__<br />
</code></p>
<p>This is output:<br />
<code><br />
result : $VAR1 = [<br />
          {<br />
            'key2' =&gt; 'trim me too!',<br />
            'key1' =&gt; 'trim me!'<br />
          },<br />
          [<br />
            'some element to trim',<br />
            'another one'<br />
          ],<br />
          'a simple string needing trimming'<br />
        ];<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Vinny</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-212</link>
		<dc:creator>Vinny</dc:creator>
		<pubDate>Sun, 14 Jun 2009 16:51:50 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-212</guid>
		<description>Hi Christine. There are 2 ways of doing it: one is to copy the values passed by @_ into lexical variables and then return the trimmed copy (pass by value) and the other is to work directly on the variables passed (pass by reference). When you work on a reference (like I did with trim()), there&#039;s no need to return the data since the original is modified automagically.

Here&#039;s another example of passing by reference:

&lt;code&gt;
my @array = (1,2,3,4,5);
for my $i (@array) {  # each element is referenced into $i
    $i++;
}
print &quot;@array&quot;; # 2 3 4 5 6
&lt;/code&gt;

Now, if I had specified a lexical for each element...
&lt;code&gt;
my @array = (1,2,3,4,5);
for my $i (@array) {  # each element is referenced into $i and then copied into $val
    my $val = $i;    
    $val++;
}
print &quot;@array&quot;; # 1 2 3 4 5
&lt;/code&gt;

The auto-incremented result stays in &lt;code&gt;$val&lt;/code&gt; which is lost with each iteration of the loop. I would have had to assign it back into &lt;code&gt;$i&lt;/code&gt; in order to change &lt;code&gt;@array&lt;/code&gt;

Cheers!</description>
		<content:encoded><![CDATA[<p>Hi Christine. There are 2 ways of doing it: one is to copy the values passed by @_ into lexical variables and then return the trimmed copy (pass by value) and the other is to work directly on the variables passed (pass by reference). When you work on a reference (like I did with trim()), there&#8217;s no need to return the data since the original is modified automagically.</p>
<p>Here&#8217;s another example of passing by reference:</p>
<p><code><br />
my @array = (1,2,3,4,5);<br />
for my $i (@array) {  # each element is referenced into $i<br />
    $i++;<br />
}<br />
print "@array"; # 2 3 4 5 6<br />
</code></p>
<p>Now, if I had specified a lexical for each element&#8230;<br />
<code><br />
my @array = (1,2,3,4,5);<br />
for my $i (@array) {  # each element is referenced into $i and then copied into $val<br />
    my $val = $i;<br />
    $val++;<br />
}<br />
print "@array"; # 1 2 3 4 5<br />
</code></p>
<p>The auto-incremented result stays in <code>$val</code> which is lost with each iteration of the loop. I would have had to assign it back into <code>$i</code> in order to change <code>@array</code></p>
<p>Cheers!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christine Morton</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-211</link>
		<dc:creator>Christine Morton</dc:creator>
		<pubDate>Sun, 14 Jun 2009 16:29:51 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-211</guid>
		<description>I think when you&#039;re using the array or hash, after you&#039;ve trimmed it you have to put it back in the array or hash, otherwise you&#039;re just trimming your own copy. Have I missed something?</description>
		<content:encoded><![CDATA[<p>I think when you&#8217;re using the array or hash, after you&#8217;ve trimmed it you have to put it back in the array or hash, otherwise you&#8217;re just trimming your own copy. Have I missed something?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: barefootcoder</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-202</link>
		<dc:creator>barefootcoder</dc:creator>
		<pubDate>Thu, 11 Jun 2009 17:38:06 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-202</guid>
		<description>Alexandr is correct.  Given your trim (with prototype):

&lt;code&gt;
#! /usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @test = (&#039;  first string   &#039;);
trim(@test);
print Dumper(@test);
&lt;/code&gt;

prints:

&lt;code&gt;
main::trim() called too early to check prototype at trimtest.pl line 13.
main::trim() called too early to check prototype at trimtest.pl line 18.
$VAR1 = &#039;  first string   &#039;;
&lt;/code&gt;

But remove the prototype and the same code gives you:

&lt;code&gt;
$VAR1 = &#039;first string&#039;;
&lt;/code&gt;

See also &lt;a href=&quot;http://www.perl.com/language/misc/fmproto.html&quot; rel=&quot;nofollow&quot;&gt;Prototypes Considered Harmful&lt;/a&gt; by Tom Christiansen.</description>
		<content:encoded><![CDATA[<p>Alexandr is correct.  Given your trim (with prototype):</p>
<p><code><br />
#! /usr/bin/perl</p>
<p>use strict;<br />
use warnings;</p>
<p>use Data::Dumper;</p>
<p>my @test = ('  first string   ');<br />
trim(@test);<br />
print Dumper(@test);<br />
</code></p>
<p>prints:</p>
<p><code><br />
main::trim() called too early to check prototype at trimtest.pl line 13.<br />
main::trim() called too early to check prototype at trimtest.pl line 18.<br />
$VAR1 = '  first string   ';<br />
</code></p>
<p>But remove the prototype and the same code gives you:</p>
<p><code><br />
$VAR1 = 'first string';<br />
</code></p>
<p>See also <a href="http://www.perl.com/language/misc/fmproto.html" rel="nofollow">Prototypes Considered Harmful</a> by Tom Christiansen.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alexandr Ciornii</title>
		<link>http://usestrict.net/2009/06/10/recursion-with-perl-and-cds/comment-page-1/#comment-201</link>
		<dc:creator>Alexandr Ciornii</dc:creator>
		<pubDate>Thu, 11 Jun 2009 13:32:55 +0000</pubDate>
		<guid isPermaLink="false">http://usestrict.net/?p=720#comment-201</guid>
		<description>Vinny: Try this test with prototype:

#!/usr/bin/perl

use 5.008;
use strict;
use warnings;
use Test::More qw(no_plan);
sub trim {
...
}

my $c=&#039; test &#039;;
trim($c);
is($c,&#039;test&#039;);
my @d=(&#039; a &#039;,&#039;b&#039;);
trim(@d);
is($d[0],&#039;a&#039;);
is($d[1],&#039;b&#039;);</description>
		<content:encoded><![CDATA[<p>Vinny: Try this test with prototype:</p>
<p>#!/usr/bin/perl</p>
<p>use 5.008;<br />
use strict;<br />
use warnings;<br />
use Test::More qw(no_plan);<br />
sub trim {<br />
&#8230;<br />
}</p>
<p>my $c=&#8217; test &#8216;;<br />
trim($c);<br />
is($c,&#8217;test&#8217;);<br />
my @d=(&#8216; a &#8216;,&#8217;b');<br />
trim(@d);<br />
is($d[0],&#8217;a');<br />
is($d[1],&#8217;b');</p>
]]></content:encoded>
	</item>
</channel>
</rss>
