Re: how to recursion
I asked this just b/c I want to do matrix calculation in perl. I found under some conditions a recursion is more effective. Thanks everybody. On 2017/3/29 23:31, Chas. Owens wrote: On Tue, Mar 28, 2017 at 9:27 PM PYH <p...@vodafonemail.de <mailto:p...@vodafonemail.de>> wrote: Hi, what's the better way to write a recursion in perl's class? sub my_recursion { my $self = shift; if (...) { $self->my_recursion; } } this one? Define better. In general that is the right form (assuming there is some side effect to calling my_recursion that will cause the if statement to be false). If your function is tail recursive and it has the potential to be deeply nested, then you can take advantage of a quirk of goto to make it faster and use less memory: #!/usr/bin/perl use strict; use warnings; { package A; sub new { bless {}, shift } sub recur { my ($self, $n) = @_; return "recur done" if $n <= 0; return $self->recur($n - 1); } sub tail_recur { my ($self, $n) = @_; return "tail_recur done" if $n <= 0; @_ = ($self, $n - 1); goto _recur; } } my $o = A->new; print $o->recur(1_000_000), "\n"; print $o->tail_recur(1_000_000), "\n"; NOTE: this only works if the code is tail recursive. That is, the recursive function does nothing but return the next call's return value. It works by replacing the function with itself rather than pushing another copy of the function on the stack. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Fw: how to recursion
Forwarding to the list. Begin forwarded message: Date: Wed, 29 Mar 2017 11:32:08 -0400 From: Shawn H Corey <shawnhco...@gmail.com> To: Shlomi Fish <shlo...@shlomifish.org> Subject: Re: how to recursion On Wed, 29 Mar 2017 17:22:36 +0300 Shlomi Fish <shlo...@shlomifish.org> wrote: > my_recursion accepts $self as its first argument, so you should pass > it there. Doing «my_recursion($self);» is one option for doing that > but : 1. It looks ugly. 2. It's less future proof. 3. It's a bad > practice for OOP perl. > > The original code was fine. Oops, you're right. the OOLs I've been using lately take care self (or this) automatically. I had forgotten that Perl is an OO toolkit, not an OOL. ☺ -- Don't stop where the ink does. Shawn H Corey -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: how to recursion
On Tue, Mar 28, 2017 at 9:27 PM PYH <p...@vodafonemail.de> wrote: > Hi, > > what's the better way to write a recursion in perl's class? > > sub my_recursion { > my $self = shift; > > if (...) { > $self->my_recursion; > } > } > > this one? > Define better. In general that is the right form (assuming there is some side effect to calling my_recursion that will cause the if statement to be false). If your function is tail recursive and it has the potential to be deeply nested, then you can take advantage of a quirk of goto to make it faster and use less memory: #!/usr/bin/perl use strict; use warnings; { package A; sub new { bless {}, shift } sub recur { my ($self, $n) = @_; return "recur done" if $n <= 0; return $self->recur($n - 1); } sub tail_recur { my ($self, $n) = @_; return "tail_recur done" if $n <= 0; @_ = ($self, $n - 1); goto _recur; } } my $o = A->new; print $o->recur(1_000_000), "\n"; print $o->tail_recur(1_000_000), "\n"; NOTE: this only works if the code is tail recursive. That is, the recursive function does nothing but return the next call's return value. It works by replacing the function with itself rather than pushing another copy of the function on the stack.
Re: how to recursion
Hi Shawn! On Wed, 29 Mar 2017 08:09:12 -0400 Shawn H Coreywrote: > On Wed, 29 Mar 2017 09:25:06 +0800 > PYH wrote: > > > sub my_recursion { > > my $self = shift; > > > > if (...) { > > $self->my_recursion; > > # you don't need $self. subroutine lookup starts > # in the same package. Just the sub by itself > # is good enough. > my_recursion(); > my_recursion accepts $self as its first argument, so you should pass it there. Doing «my_recursion($self);» is one option for doing that but : 1. It looks ugly. 2. It's less future proof. 3. It's a bad practice for OOP perl. The original code was fine. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: how to recursion
On Wed, 29 Mar 2017 09:25:06 +0800 PYH <p...@vodafonemail.de> wrote: > sub my_recursion { > my $self = shift; > > if (...) { > $self->my_recursion; # you don't need $self. subroutine lookup starts # in the same package. Just the sub by itself # is good enough. my_recursion(); > } > } More thoughts on recursion: https://lookatperl.blogspot.ca/2012/11/a-look-at-recursion.html -- Don't stop where the ink does. Shawn H Corey -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: how to recursion
On 03/28/2017 09:25 PM, PYH wrote: Hi, what's the better way to write a recursion in perl's class? sub my_recursion { my $self = shift; if (...) { $self->my_recursion; } } this one? i am not sure what you mean by better. your code would work if you finished it with a proper argument check. recursive code must always have a clean way to end the recursion and pop up the stack. and you don't need OO to do recursion either. perl supports recursion in general. uri -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
how to recursion
Hi, what's the better way to write a recursion in perl's class? sub my_recursion { my $self = shift; if (...) { $self->my_recursion; } } this one? thanks. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
generate XML from recursion
Hi, Thanks for the solutions of the recent problems. I would like to traverse a dir on the HDD at a part of the XML generation. So I generated about 75% of an xml file with xml::writer, and it comes a Projectstructure tag. Between these tag I simply list a dir into empty tags Object attr=./. If recursion is ready, the closing Projectstructure tag closes it. And non recursive XML generation continues. $output = IO::File-new(default.xml); $writer = XML::Writer-new(OUTPUT = $output, DATA_MODE = 1, DATA_INDENT = , ENCODING = utf-8, NEWLINES = 0 ); Traverse($dir, $writer); sub Traverse { opendir(DIR, $dir) or die Cannot open directory $dir: $!\n; my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { # generate XML here print $file; if(-d $file and ($file !~ /^\.\.?$/) ) { # make dir branch Traverse($file); } $writer-emptyTag(Object, Name = $file); # make file branch } } ... $writer-startTag(ProjectStructure); Traverse(C:\\ph); $writer-endTag(ProjectStructure); But it gives a hideous error: Attempt to insert empty tag after close of document element at t2tot3Project line 72. How can it be? I call the subrutine in the middle of a tag. How can be the document closed? Tamas
Re: generate XML from recursion
On Wed, Jul 8, 2015 at 10:51 AM, Nagy Tamas (TVI-GmbH) tamas.n...@tvi-gmbh.de wrote: How can it be? I call the subroutine in the middle of a tag. How can be the document closed? Well, I don't get that (could it be that call to Travers($dir,$writer); before the sub def?) but to get your code to work I had to keep the dir involved sub Traverse { my $dir = shift; opendir(DIR, $dir) or die Cannot open directory $dir: $!\n; my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { # generate XML here if(-d $dir/$file and ($file !~ /^\.\.?$/) ) { # make dir branch Traverse($dir/$file); } -- a Andy Bach, afb...@gmail.com 608 658-1890 cell 608 261-5738 wk
Re: Can recursion eliminate nested foreach() loops?
On 2012-02-27 03:52, Shawn H Corey wrote: There is no simplify way of doing this. perl -wle ' my $s = {red,green,blue},{small,large},{light,dark}; print for glob $s; ' -- Ruud -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On Sun, Feb 26, 2012 at 09:30:44PM -0500, Steve Bertrand wrote: I came across a question early this morning on a forum that intrigued me. I literally spent about five hours trying everything to solve it, but I couldn't. Sometimes Perl is just a means to get at the corect tool: my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; local $ = ,; say y/-/ /r for glob join -, map {@{$_-{values}}}, @$attributes; red small light red small dark red large light red large dark green small light green small dark green large light green large dark blue small light blue small dark blue large light blue large dark or perhaps you like commas but dislike maintenance programmers: my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; $=,;say for(glob(qq{@{[map+qq{{@{$_-{values,@$attributes]}})) red,small,light red,small,dark red,large,light red,large,dark green,small,light green,small,dark green,large,light green,large,dark blue,small,light blue,small,dark blue,large,light blue,large,dark The key here is using globbing. See perldoc -f glob for the details. Using bsd_glob would clean up the (first) code a little. I know this isn't a beginner's question None of the concepts in this code are particularly tricky, but there are quite a few of them in a short piece of code. Is there a way to simplify this within Perl? I suppose the question of whether or not this is simplified comes down to definitions. -- Paul Johnson - p...@pjcj.net http://www.pjcj.net -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Can recursion eliminate nested foreach() loops?
I came across a question early this morning on a forum that intrigued me. I literally spent about five hours trying everything to solve it, but I couldn't. Every attempt at recursion, counting, numbering, hashing etc failed. Is there a way to use recursion to eliminate the repeated and pre-calculated calls to foreach as this OP is asking? From ... .. ... is verbatim 'dms000' ... I need to generate a list of combinations from a data structure such as: my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; It is easy enough when the number of types are known: my @combos = (); foreach my $a (@{$attributes-[0]-{values}}) { foreach my $b (@{$attributes-[1]-{values}}) { foreach my $c (@{$attributes-[2]-{values}}) { push @combos, [$a, $b, $c]; } } } Which results in a list such as: red small light red small dark red large light red large dark green small light ... But how to do with arbitrary number of types? Obviously will need recursion but I can't figure it out. The only thing I could come up with was generating code like code2 as a string and eval()ing it...a poor solution. ... I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? Steve -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On 12-02-26 09:30 PM, Steve Bertrand wrote: I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? There is no simplify way of doing this. Separate off the first attribute and cross-product it with a recursive call to the rest. Like this: #!/usr/bin/env perl use strict; use warnings; my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; sub combo { my @traits = @_; # nothing given, nothing returned return if @traits == 0; # return the last list if( @traits == 1 ){ return map { [ $_ ] } @{ $traits[0]{values} }; } # get the combos for everything but the first one my @combos = combo( @traits[ 1 .. $#traits ] ); # now combine them my @result = (); for my $first ( @{ $traits[0]{values} } ){ for my $rest ( @combos ){ push @result, [ $first, @$rest ]; } } return @result; } my @list = combo( @$attributes ); for my $set ( @list ){ print @$set\n; } __END__ -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. It's Mutual Aid, not fierce competition, that's the dominate force of evolution. Of course, anyone who has worked in open source already knows this. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On 2012-02-26 21:52, Shawn H Corey wrote: On 12-02-26 09:30 PM, Steve Bertrand wrote: I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? There is no simplify way of doing this. Separate off the first attribute and cross-product it with a recursive call to the rest. Like this: #!/usr/bin/env perl use strict; use warnings; my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; sub combo { my @traits = @_; # nothing given, nothing returned return if @traits == 0; # return the last list if( @traits == 1 ){ return map { [ $_ ] } @{ $traits[0]{values} }; } # get the combos for everything but the first one my @combos = combo( @traits[ 1 .. $#traits ] ); # now combine them my @result = (); for my $first ( @{ $traits[0]{values} } ){ for my $rest ( @combos ){ push @result, [ $first, @$rest ]; } } return @result; } my @list = combo( @$attributes ); for my $set ( @list ){ print @$set\n; } Tres Bien!!! Merci Beaucoup!! Thank you so much :) I will pour over this code until I completely understand it. I knew I came to the right place! Steve -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On 2012-02-26 21:52, Shawn H Corey wrote: On 12-02-26 09:30 PM, Steve Bertrand wrote: I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? There is no simplify way of doing this. Separate off the first attribute and cross-product it with a recursive call to the rest. Like this: fyi: http://forums.devshed.com/perl-programming-6/recursion-help-882763.html Steve -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On 27/02/2012 02:30, Steve Bertrand wrote: I came across a question early this morning on a forum that intrigued me. I literally spent about five hours trying everything to solve it, but I couldn't. Every attempt at recursion, counting, numbering, hashing etc failed. Is there a way to use recursion to eliminate the repeated and pre-calculated calls to foreach as this OP is asking? From ... .. ... is verbatim 'dms000' ... I need to generate a list of combinations from a data structure such as: my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; It is easy enough when the number of types are known: my @combos = (); foreach my $a (@{$attributes-[0]-{values}}) { foreach my $b (@{$attributes-[1]-{values}}) { foreach my $c (@{$attributes-[2]-{values}}) { push @combos, [$a, $b, $c]; } } } Which results in a list such as: red small light red small dark red large light red large dark green small light ... But how to do with arbitrary number of types? Obviously will need recursion but I can't figure it out. The only thing I could come up with was generating code like code2 as a string and eval()ing it...a poor solution. ... I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? Hi Steve Much of the complexity comes from working with the nested data structure. Writing a subroutine that takes just a set of the 'values' arrays cleans things up a lot. Take a look at the program below. HTH, Rob use strict; use warnings; my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; print $_\n foreach combos(map $_-{values}, @$attributes); sub combos { my $first = shift; return @$first unless @_; my @combinations; foreach my $beg (@$first) { foreach my $end (combos(@_)) { push @combinations, $beg $end; } } return @combinations; } **OUTPUT** red small light red small dark red large light red large dark green small light green small dark green large light green large dark blue small light blue small dark blue large light blue large dark -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Can recursion eliminate nested foreach() loops?
On 2012-02-26 23:55, Rob Dixon wrote: On 27/02/2012 02:30, Steve Bertrand wrote: I know this isn't a beginner's question, but I know there are geniuses here. Is there a way to simplify this within Perl? Hi Steve Much of the complexity comes from working with the nested data structure. Writing a subroutine that takes just a set of the 'values' arrays cleans things up a lot. Take a look at the program below. In my mind, I knew that map() had to fit in someplace, but by the time I thought about map, I was ready to ask for help instead of performing the Schwartzian Transform physically on my keyboard :) This is another great piece of code I (and others) can study. I'm leaving it below. Thank you Rob! use strict; use warnings; my $attributes = [ { type = 'colors', values = [qw/red green blue/] }, { type = 'sizes', values = [qw/small large/] }, { type = 'shades', values = [qw/light dark/] }, ]; print $_\n foreach combos(map $_-{values}, @$attributes); sub combos { my $first = shift; return @$first unless @_; my @combinations; foreach my $beg (@$first) { foreach my $end (combos(@_)) { push @combinations, $beg $end; } } return @combinations; } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: [PBML] Help needed in recursion with objects in perl !
On Fri, Aug 6, 2010 at 8:09 PM, Randal L. Schwartz mer...@stonehenge.comwrote: Amit == Amit Saxena learn.tech...@gmail.com writes: Amit I am working on a tree implementation (with any number of parent Amit and child nodes) in perl. Every node is defined as a object of a Amit Node class which I have created as a .pm module. Unless this is for a student exercise, you probably just want to look at Graph in the CPAN. Lots and lots and lots of graph traversal things already worked out for you. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion Thanks Randal for the reply. The purpose of this activity is to model a hierarchical representation of dependent components, each of one will be represented as a service. I had a look at the Graph module ( http://search.cpan.org/~jhi/Graph-0.94/lib/Graph.pod) but I am not sure how it can be used to implement multiple parent and multiple child implementation of a tree. In other words, I would like to have similar methods which are available in the Tree implementations in CPAN. Please suggest. Thanks Regards, Amit Saxena
Re: [PBML] Help needed in recursion with objects in perl !
On Sat, Aug 7, 2010 at 09:36, Amit Saxena learn.tech...@gmail.com wrote: snip The purpose of this activity is to model a hierarchical representation of dependent components, each of one will be represented as a service. I had a look at the Graph module ( http://search.cpan.org/~jhi/Graph-0.94/lib/Graph.pod) but I am not sure how it can be used to implement multiple parent and multiple child implementation of a tree. In other words, I would like to have similar methods which are available in the Tree implementations in CPAN. snip A [tree][0] is a [Graph][1]. Often you will see trees implemented as [Directed Acyclic Graphs][2] (or DAGs) because pointers or references only flow one way. Here is an example using the [Graph][3] module: #!/usr/bin/perl use strict; use warnings; use Graph; #FIXME: naive implementation, there may be a much better way to do this sub run_in_parallel { my $g = shift-copy; while (my @v = $g-vertices) { my @run = grep { $g-is_successorless_vertex($_) } @v; print running , join(, , @run), in parallel\n; for my $compenent (@run) { $g-delete_vertex($compenent); }; } } my $g = Graph-new; my $f = Graph-new; while (DATA) { my ($component, @dependencies) = split; unless ($g-has_vertex($component)) { $g-add_vertex($component); $f-add_vertex($component); } for my $dependency (@dependencies) { unless ($g-has_vertex($dependency)) { $g-add_vertex($dependency); $f-add_vertex($dependency); } $g-add_edge($dependency, $component); $f-add_edge($component, $dependency); } } print everything will work if you run the programs in this order: , join(, , $g-topological_sort), \n; run_in_parallel($f); #component dependency list __DATA__ a b c d b e c f g d e f g [0]: http://en.wikipedia.org/wiki/Tree_(graph_theory) [1]: http://en.wikipedia.org/wiki/Graph_(mathematics) [2]: http://en.wikipedia.org/wiki/Directed_acyclic_graph [3]: http://search.cpan.org/dist/Graph/lib/Graph.pod -- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Help needed in recursion with objects in perl !
Hi all, I am working on a tree implementation (with any number of parent and child nodes) in perl. Every node is defined as a object of a Node class which I have created as a .pm module. I have defined a method getParentNodes which returns reference to an array having all the (immediate) parent nodes objects as shown below. my @immediate_parent_node_objects = $node1-getParentNodes (); my $i; foreach $i ( @{$node1-getParentNodes ()} ) { print Parent node for the child node . $node1-getNodeName() . is . $i-getNodeName() \n; } I want to define another method named getParentNodesRecurse which will return either all or upto a level of (ancestor) parent nodes objects instead of immediate parent node objects. I tried to implement something similar to what's shown below but I am unable to achieve it. sub getParentNodesRecurse { my ( $self, $level ) = @_; print \t x $level . node name = [ . $self-getNodeName() . ], level = [$level]\n; #print level = [$level]\n; if ( ! defined $self-getParentNodes() ) { print \t x $level . (No parent nodes for the node [ . $self-getNodeName() . ])\n; return; } my @concatenated_list_of_parent_nodes; my $l; foreach $l ( @{$self-getParentNodes()} ) { @concatenated_list_of_parent_nodes = ( @concatenated_list_of_parent_nodes, getParentNodesRecurse( $l, $level+1 ) ); } print \n; print Returning the concatenation of following two lists : \n; print . @{$self-getParentNodes()} . \n; print [ . @concatenated_list_of_parent_nodes . ]\n; print \n; return ( \( @{$self-getParentNodes()}, @concatenated_list_of_parent_nodes ) ); } Please help and also let me know in case there is a better way to implement. I can even rewrite my implementation using different design. I tried looking for modules on CPAN which supports tree implementation with multiple parents and child but couldn't find it. Note : For some reasons, I don't want to use implementation which requires $_. Thanks Regards, Amit Saxena
Re: [PBML] Help needed in recursion with objects in perl !
Amit == Amit Saxena learn.tech...@gmail.com writes: Amit I am working on a tree implementation (with any number of parent Amit and child nodes) in perl. Every node is defined as a object of a Amit Node class which I have created as a .pm module. Unless this is for a student exercise, you probably just want to look at Graph in the CPAN. Lots and lots and lots of graph traversal things already worked out for you. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: File::Find NO RECURSION Howto
On Monday 01 Mar 2010 19:31:15 Shawn H Corey wrote: Shlomi Fish wrote: Well, Matt S. Trout shared his sentiments about I cannot use CPAN here: http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ Well, Matt is wrong. You can't always use CPAN. Yes, you can set it up so you can use it in development, but that doesn't mean you can do it in production. I have worked in places where the policy was no software that's not approved by the sysadmins and approval of a single module may take 6 to 18 months. They're even very strict about downloading a copy and cut paste. A foolish policy, kinda like, our horse will never get sick from bad grain if we never feed it but managers _always_ know best. ;) Heh, tell me about it. Medium-to-large businesses shoot themselves in the foot by incorporating these god-awful policies and becoming very non-agile. Then they wonder why startups with much fewer resources can often easily out- compete them. I read somewhere (Paul Graham I think, but I can no longer find it) that as companies grow they adopt more and more rules and regulations after learning from mistakes they made in the past. But these rules prevent a lot of legitimate actions and in turn make the company much less agile. And sometimes they impose these rules on start-ups that they buy. It was later compared to http://en.wikipedia.org/wiki/Sarbanes%E2%80%93Oxley_Act which killed the IPOs in .us and was another regulation that was passed and which had unwanted side- effects. In any case, such antagonism towards using third-party code will make the person working for such companies beyond help and doomed anyway you look at it, so we can ignore it. Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Understand what Open Source is - http://shlom.in/oss-fs Deletionists delete Wikipedia articles that they consider lame. Chuck Norris deletes deletionists whom he considers lame. Please reply to list if it's a mailing list post - http://shlom.in/reply . -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
File::Find NO RECURSION Howto
Hi, How can I stop File::Find to go below current dir? i.e. no recursion. Although I can use glob or * to get file names in current dir. But I wanted to know if File::Find has a maxdepth limit like linux find. The script I created uses a switch which decides if recursion is allowed or not. It uses the system find like this.. open(FIND, find -maxdepth $recursive | ); I wanted to remove this dependency on system find. Is it possible with File::Find? I tried this after googling http://www.perlmonks.org/?node_id=676958 sub wanted { if ( -d ) { # should I write this as -d $File::Find::name $File::Find::prune = 1; return; } print $File::Find::name . \n; }
Re: File::Find NO RECURSION Howto
raphael() wrote: Hi, How can I stop File::Find to go below current dir? i.e. no recursion. Although I can use glob or * to get file names in current dir. But I wanted to know if File::Find has a maxdepth limit like linux find. The script I created uses a switch which decides if recursion is allowed or not. It uses the system find like this.. open(FIND, find -maxdepth $recursive | ); I wanted to remove this dependency on system find. Is it possible with File::Find? I tried this after googling http://www.perlmonks.org/?node_id=676958 sub wanted { if ( -d ) { # should I write this as -d $File::Find::name # No, this is shorthand for: if( -d $_ ){ $File::Find::prune = 1; return; } print $File::Find::name . \n; } And didn't it work? The if statement works on all directories. This means that all directories except the top-level one will not be searched. -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. I like Perl; it's the only language where you can bless your thingy. Eliminate software piracy: use only FLOSS. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: File::Find NO RECURSION Howto
On Monday 01 Mar 2010 13:23:16 raphael() wrote: Hi, How can I stop File::Find to go below current dir? i.e. no recursion. Although I can use glob or * to get file names in current dir. But I wanted to know if File::Find has a maxdepth limit like linux find. Not, by itself, but there are wrappers around it that provides you with it. And there are several alternative modules like File-Find-Object or File-Next that solve some of its inherent philosophical limitations. For a summary see: * http://www.shlomifish.org/open-source/projects/File-Find-Object/ * http://www.perlfoundation.org/perl5/index.cgi?alternatives_to_file_find The script I created uses a switch which decides if recursion is allowed or not. It uses the system find like this.. open(FIND, find -maxdepth $recursive | ); I wanted to remove this dependency on system find. Is it possible with File::Find? It is possible. I tried this after googling http://www.perlmonks.org/?node_id=676958 sub wanted { if ( -d ) { # should I write this as -d $File::Find::name $File::Find::prune = 1; return; } print $File::Find::name . \n; } Well, this will only be equivalent to -maxdepth 1 not to larger values. I can't tell you offhand whether it's -d $_ or -d $File::Find::name because the File::Find interface is evil-incarnate and I'm trying to forget it. If you want to prune after an arbitrary maxdepth, you'll need to keep track of the current depth and the level there. May be File::Find gives you that but you really should be using File::Find::Object, File::Find::Rule or File::Find::Object::Rule . Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ What does Zionism mean? - http://shlom.in/def-zionism Deletionists delete Wikipedia articles that they consider lame. Chuck Norris deletes deletionists whom he considers lame. Please reply to list if it's a mailing list post - http://shlom.in/reply . -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: File::Find NO RECURSION Howto
On Mon, Mar 1, 2010 at 6:18 PM, Shawn H Corey shawnhco...@gmail.com wrote: raphael() wrote: Hi, How can I stop File::Find to go below current dir? i.e. no recursion. Although I can use glob or * to get file names in current dir. But I wanted to know if File::Find has a maxdepth limit like linux find. The script I created uses a switch which decides if recursion is allowed or not. It uses the system find like this.. open(FIND, find -maxdepth $recursive | ); I wanted to remove this dependency on system find. Is it possible with File::Find? I tried this after googling http://www.perlmonks.org/?node_id=676958 sub wanted { if ( -d ) { # should I write this as -d $File::Find::name # No, this is shorthand for: if( -d $_ ){ $File::Find::prune = 1; return; } print $File::Find::name . \n; } And didn't it work? The if statement works on all directories. This means that all directories except the top-level one will not be searched. -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. I like Perl; it's the only language where you can bless your thingy. Eliminate software piracy: use only FLOSS. Nope. It ddn't work. Any ideas? I am thinking to use File::Find::Rule. But I didn't want any module dependency for this script. And Shlomi your message came in while I was typing this. Going to check the modules you mentioned. But it would have been great if I didn't has to use a module :( The people around me no sh*t about installing perl modules from CPAN. Thanks all. PS - Shlomi, your website is GOOD!
Re: File::Find NO RECURSION Howto
On Monday 01 Mar 2010 15:00:26 raphael() wrote: On Mon, Mar 1, 2010 at 6:18 PM, Shawn H Corey shawnhco...@gmail.com wrote: raphael() wrote: Hi, How can I stop File::Find to go below current dir? i.e. no recursion. Although I can use glob or * to get file names in current dir. But I wanted to know if File::Find has a maxdepth limit like linux find. The script I created uses a switch which decides if recursion is allowed or not. It uses the system find like this.. open(FIND, find -maxdepth $recursive | ); I wanted to remove this dependency on system find. Is it possible with File::Find? I tried this after googling http://www.perlmonks.org/?node_id=676958 sub wanted { if ( -d ) { # should I write this as -d $File::Find::name # No, this is shorthand for: if( -d $_ ){ $File::Find::prune = 1; return; } print $File::Find::name . \n; } And didn't it work? The if statement works on all directories. This means that all directories except the top-level one will not be searched. -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. I like Perl; it's the only language where you can bless your thingy. Eliminate software piracy: use only FLOSS. Nope. It ddn't work. Any ideas? I am thinking to use File::Find::Rule. But I didn't want any module dependency for this script. You can look at how File::Find::Rule does it and duplicate the logic. And Shlomi your message came in while I was typing this. Going to check the modules you mentioned. Thanks. But it would have been great if I didn't has to use a module :( The people around me no sh*t about installing perl modules from CPAN. Well, Matt S. Trout shared his sentiments about I cannot use CPAN here: http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ I've placed a link to it here: http://perl-begin.org/topics/cpan/ Thanks all. PS - Shlomi, your website is GOOD! Thanks for the compliment! If possible, please share it with your friends and on social-bookmarking/social-networks/etc. sites that you belong to. BTW, you shoulnd't highlight words using all-uppercase-letters. (It's considered akin to shouting). Instead use *...* , /.../ or _..._ . Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Optimising Code for Speed - http://shlom.in/optimise Deletionists delete Wikipedia articles that they consider lame. Chuck Norris deletes deletionists whom he considers lame. Please reply to list if it's a mailing list post - http://shlom.in/reply . -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: File::Find NO RECURSION Howto
Shlomi Fish wrote: Well, Matt S. Trout shared his sentiments about I cannot use CPAN here: http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ Well, Matt is wrong. You can't always use CPAN. Yes, you can set it up so you can use it in development, but that doesn't mean you can do it in production. I have worked in places where the policy was no software that's not approved by the sysadmins and approval of a single module may take 6 to 18 months. They're even very strict about downloading a copy and cut paste. A foolish policy, kinda like, our horse will never get sick from bad grain if we never feed it but managers _always_ know best. ;) -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. I like Perl; it's the only language where you can bless your thingy. Eliminate software piracy: use only FLOSS. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Understanding recursion
Hi, I was reading Higher Order Perl[1] last night and, dishearteningly, got stuck on chapter one. Mark Dominus offers the following as a binary string conversion example of how recursion can work. use strict; use warnings; my $bstr = binary(37); print $bstr\n; # prints 100101 sub binary { my ($n) = @_; return $n if $n == 0 || $n == 1; my $k = int($n/2); my $b = $n % 2; my $E = binary($k); return $E . $b; } The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of 37 % 2 =1 18 % 2 = 0 9 % 2 = 1 4 % 2 = 0 2 % 2 = 0 That by my reckoning is 10100. Almost the reverse of the answer but I am obviously wrong and I can't see how the final expressions: my $E = binary($k); return $E . $b; work to give the answer. Can someone more enlightened than me give me some guidence. Thanx, Dp. PS: Has anybody heard from Rob Dixon, he hasn't been on the list for ages. 1. http://hop.perl.plover.com/book -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
On Fri, 2009-07-10 at 09:26 +0100, Dermot wrote: The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of 37 % 2 =1 18 % 2 = 0 9 % 2 = 1 4 % 2 = 0 2 % 2 = 0 That by my reckoning is 10100. Almost the reverse of the answer but I am obviously wrong and I can't see how the final expressions: my $E = binary($k); return $E . $b; work to give the answer. Can someone more enlightened than me give me some guidence. Perhaps it would be easier to understand if we look at the counterpart to this. #!/usr/bin/perl my $dstr = decimal( 123456789 ); print $dstr\n; sub decimal { my ($n) = @_; return $n if $n 10; my $k = int($n/10); my $b = $n % 10; my $E = decimal($k); return $E . $b; } __END__ When dealing with the number 123456789, the first time through, stopping just before the sub is called a second time, we have: $b = 123456789 % 10 = 9; $k = int( 123456789 / 10 ) = 12345678; $E will be assigned the string that represents $k. Clearly, this must be concatenated before $b in the returned string. The binary version works the same way. -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
2009/7/10 Shawn H. Corey shawnhco...@gmail.com: On Fri, 2009-07-10 at 09:26 +0100, Dermot wrote: The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of 37 % 2 =1 18 % 2 = 0 9 % 2 = 1 4 % 2 = 0 2 % 2 = 0 That by my reckoning is 10100. Almost the reverse of the answer but I am obviously wrong and I can't see how the final expressions: my $E = binary($k); return $E . $b; work to give the answer. Can someone more enlightened than me give me some guidence. Perhaps it would be easier to understand if we look at the counterpart to this. I appreciate what your saying but I can't say I find the counterpart to be more helpful so I am going to stick to the binary if it's all the same. #!/usr/bin/perl my $dstr = decimal( 123456789 ); print $dstr\n; sub decimal { my ($n) = @_; return $n if $n 10; my $k = int($n/10); my $b = $n % 10; my $E = decimal($k); return $E . $b; } __END__ When dealing with the number 123456789, the first time through, stopping just before the sub is called a second time, we have: $b = 123456789 % 10 = 9; $k = int( 123456789 / 10 ) = 12345678; $E will be assigned the string that represents $k. Why is $E getting assigned the value from $k? $E is initialised and then assigned the return value of the binary(18) during the first invocation (0). Does the subroutine continue and concatenate $b to $E and then return (1) ? or does it wait until binary exhausts $n? In my own groping/nonscientific sort of way, what I see emerging is a pattern where my result (10100) is nearly the reverse of the correct answer (100101) minus the leading 1. If that is correct I don't know why the string is reversed, Clearly, this must be concatenated before $b in the returned string. The binary version works the same way. Lost you a bit there because I can't see $k being concatenated to $E. Dp. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
On Fri, 2009-07-10 at 13:42 +0100, Dermot wrote: Why is $E getting assigned the value from $k? my $E = binary($k); I said $E will be assigned the string that represents $k, not it's value. $E is initialised and then assigned the return value of the binary(18) during the first invocation (0). Does the subroutine continue and concatenate $b to $E and then return (1) ? or does it wait until binary exhausts $n? It waits until: $n == 0 || $n == 1; In my own groping/nonscientific sort of way, what I see emerging is a pattern where my result (10100) is nearly the reverse of the correct answer (100101) minus the leading 1. If that is correct I don't know why the string is reversed, Here's a breakdown of what's happening in binary(37). Note that I'm mixing arithmetic and string manipulations here. 37 = int(37/2)*2 + 37%2 = (18)*2 + 1 = ( int(18/2)*2 + 18%2 )*2 + 1 = ( (9)*2 + 0 ) + 1 = ( ( int(9/2)*2 + 9%2 )*2 + 0 )*2 + 1 = ( ( (4)*2 + 1 )*2 + 0 )*2 + 1 = ( ( ( int(4/2)*2 + 4%2 )*2 + 1 )*2 + 0 )*2 + 1 = ( ( ( (2)*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1 = ( ( ( ( int(2/2)*2 + 2%2 )*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1 = ( ( ( ( (1)*2 + 0 )*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1 = ( ( ( ( 1 . 0 ) . 0 ) . 1 ) . 0 ) . 1 = ( ( ( ( 10 ) . 0 ) . 1 ) . 0 ) . 1 = ( ( ( 100 ) . 1 ) . 0 ) . 1 = ( ( 1001 ) . 0 ) . 1 = ( 10010 ) . 1 = 100101 In the first part: $n = int($n/2)* + $n%2 but $k = int($n/2) and $b = $n%2 so $n = int($n/2)*2 + $n%2 = $k*2 + $b Addition is commutative, so this could be written as: $n = $b + $k*2 but string concatenation is not. The return string must be $E, the string representing $k; multiplied by 2 by concatenating 0 at it's end; and then that 0 being replaced by $b. In decimal, to multiply a number by 10, add an zero to it's end. (It's true. Ask anyone on the streets. When asked, How do you multiply a number by ten? they'll reply, Stick a zero at its end.) In binary, to multiply a number by two, stick an zero on its end. If $e is the string representing $k, to reconstruct $n, we have to first multiply $E by 2: my $return_string = $E . 0; Now we have to add $b to this by replacing the last character in the return string with $b: $return_string = substr( $return_string, 0, -1 ) . $b; It's just simpler to do it all in one step: my $return_string = $E . $b; -- Just my 0.0002 million dollars worth, Shawn Programming is as much about organization and communication as it is about coding. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
On Fri Jul 10 2009 @ 9:26, Dermot wrote: The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of 37 % 2 =1 18 % 2 = 0 9 % 2 = 1 4 % 2 = 0 2 % 2 = 0 That by my reckoning is 10100. Almost the reverse of the answer but I am obviously wrong and I can't see how the final expressions: my $E = binary($k); return $E . $b; work to give the answer. It helps for me to walk through it visually, indenting once each time the script needs to call the binary sub-routine. Notice that it keeps going down and inward, until it bottoms out on the base case. At that point, the answers ripple back up to fit into the calls to binary($E) that were left hanging (because in those cases $E wasn't 1 or 0). Maybe this will help you as well. Does 37 == 0 || 1? No; continue... $k = 18; $b = 1; $E = binary(18) - go do that... Does 18 == 0 || 1? No; continue... $k = 9; $b = 0; $E = binary(9) - go do that... Does 9 == 0 || 1? No; continue... $k = 4; $b = 1; $E = binary(4) - go do that... Does 4 == 0 || 1? No; continue... $k = 2; $b = 0; $E = binary(2) - go do that... Does 2 == 0 || 1? No; continue... $k = 1; $b = 0; $E = binary(1) - go do that... Does 1 == 0 || 1? Yes; return 1 $E = 1; return 1 . 0 $E = 10; return 10 . 0 $E = 100; return 100 . 1 $E = 1001; return 1001 . 0 $E = 10010; return 10010 . 1 Hope this helps, T -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
2009/7/10 Telemachus telemac...@arpinum.org: On Fri Jul 10 2009 @ 9:26, Dermot wrote: The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of It helps for me to walk through it visually, indenting once each time the script needs to call the binary sub-routine. Notice that it keeps going down and inward, until it bottoms out on the base case. At that point, the answers ripple back up to fit into the calls to binary($E) that were left hanging (because in those cases $E wasn't 1 or 0). Maybe this will help you as well. Does 37 == 0 || 1? No; continue... $k = 18; $b = 1; $E = binary(18) - go do that... Does 18 == 0 || 1? No; continue... $k = 9; $b = 0; $E = binary(9) - go do that... Does 9 == 0 || 1? No; continue... $k = 4; $b = 1; $E = binary(4) - go do that... Does 4 == 0 || 1? No; continue... $k = 2; $b = 0; $E = binary(2) - go do that... Does 2 == 0 || 1? No; continue... $k = 1; $b = 0; $E = binary(1) - go do that... Does 1 == 0 || 1? Yes; return 1 $E = 1; return 1 . 0 $E = 10; return 10 . 0 $E = 100; return 100 . 1 $E = 1001; return 1001 . 0 $E = 10010; return 10010 . 1 Yes this does help. It makes a lot more sense when I get to view the whole execution visually like this. So the final return statement (as Shawn pointed out) isn't used until $n is either 0 or 1. In effect the whole thing loops from: my ($n) = @_; return return $n if $n == 0 || $n == 1; my $k = int($n/2); my $b = $n % 2; my $E = binary($k); Then un-winds itself, returning in reverse order. I want to thank you both for the time and energy you've put in. There's been a lot of typing there and it's much appreciated. Dp. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Understanding recursion
Dermot wrote: Hi, I was reading Higher Order Perl[1] last night and, dishearteningly, got stuck on chapter one. Mark Dominus offers the following as a binary string conversion example of how recursion can work. use strict; use warnings; my $bstr = binary(37); print $bstr\n; # prints 100101 sub binary { my ($n) = @_; return $n if $n == 0 || $n == 1; my $k = int($n/2); my $b = $n % 2; my $E = binary($k); return $E . $b; } The algorithm works perfectly but my understanding of it's workings is amiss. When I look at this I see $E initialised and then concatenate with the the modulus of 37 % 2 =1 18 % 2 = 0 9 % 2 = 1 4 % 2 = 0 2 % 2 = 0 That by my reckoning is 10100. Almost the reverse of the answer but I am obviously wrong and I can't see how the final expressions: my $E = binary($k); return $E . $b; work to give the answer. Can someone more enlightened than me give me some guidence. Thanx, Dp. Maybe this will make it easier to understand. On each call 'binary' $b is set as follows (but does not start returning values until the 6th call): 1. $b = 1 (37 % 2) 2. $b = 0 (18 % 2) 3. $b = 1 (9 % 2) 4. $b = 0 (4 % 0) 5. $b = 0 (2 % 0) 6. returns 1 immediately Now the stack starts unwinding and appending the $b value to the return value: 5. returns '10' (1 from 6th call and 0 from b value on 5th call). 4. returns '100' 3. returns '1001' 2. returns '10010' 1. returns '100101' Ken _ Windows Live™: Keep your life in sync. http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009
Randal's columns (was Re: HOWTO: File Renaming and Directory Recursion)
Morbus == Morbus Iff [EMAIL PROTECTED] writes: Morbus The script was mindlessly simple, and I felt it would be a good HOWTO Morbus for the perl beginners crowd, if not to show some good code practices, Morbus but also to counteract the . .. .. . controversial HOWTO that had Morbus been posted a week or so ago. Certainly, if you find this as misguided Morbus as his, complain onlist with better examples, or offlist with anger. Not necessarily a better example, but it's always worth a quick google of site:stonehenge.com $YOUR_PERL_KEYWORDS HERE. In this case, using File::Find and rename, the first hit is: http://www.stonehenge.com/merlyn/LinuxMag/col45.html which I wrote fairly recently and covers nearly identical ground. Seriously, after 192 magazine articles, there's not *much* that isn't illustrated in that archive of http://www.stonehenge.com/merlyn/UnixReview/ http://www.stonehenge.com/merlyn/WebTechniques/ http://www.stonehenge.com/merlyn/LinuxMag/ http://www.stonehenge.com/merlyn/PerlJournal/ -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 [EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/ Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training! -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
HOWTO: File Renaming and Directory Recursion
Earlier this morning, a friend of mine asked me for a script that would given a list of files, replace underscores with spaces, to take this: Artist_Name-Track_Name.mp3 and rename it to this: Artist Name-Track Name.mp3 The script was mindlessly simple, and I felt it would be a good HOWTO for the perl beginners crowd, if not to show some good code practices, but also to counteract the . .. .. . controversial HOWTO that had been posted a week or so ago. Certainly, if you find this as misguided as his, complain onlist with better examples, or offlist with anger. The first bit of code I wrote him was below. Save for the additional explanatory comments, it's nearly exact. #!/usr/bin/perl # start all your scripts with these two lines. # they are the best teacher you will ever find for # writing perl code. they make you smarter, and # you'll last longer in bed; no drugs necessary. # use warnings; use strict; # he needed the script to read every file in a directory # and rename them based on whether they had underscores # in the name. to make the script as 'immediately runnable' # as possible, I assumed he would be placing the script # in the directory full of files, and running it there. # as such, we'll be opening the current working directory. # if anything goes wrong, we stop processing with the error. # ALWAYS CHECK FOR SUCCESS BEFORE CONTINUING. # opendir(DIR, .) or die $!; # next, we load all the files in that directory into # an array. at this point, we could also have used the # grep() function to filter out entries that weren't # relevant, but for readability I chose a more configurable # approach (see below). # my @files = readdir(DIR); close(DIR); # implicit. # now, we need to loop through all the directory files, # stored in @array. we're going to use $_ here, which # can be remembered as the thing we want to work with. # we could just as easily used an explicit variable name, # and in larger scripts, you usually want to. # while (@files) { # so, the filename is now stored in $_, and since $_ is # assumed for a number of Perl's functions, we don't # have to explicitly mention it in the following filters. # these filter serve one purpose: make sure we're working # ONLY with files we should be. these are sanity checks: # we're ensuring that we're not operating on anything we # wouldn't. this is good practice: ALWAYS CHECK YOUR SANITY. # rule out everything you don't want, and focus on everything # you do. first, we skip directories with the -d check. # the syntax I'm using below is far more readable than a bunch # of if/else statements: we're not increasing our indents, and # we don't have to worry about a zillion open/closing brackets. # it also reads more like English. # next if -d; # if we're still here, we've got a file. we'll automatically # skip files that begin with a . as they're usually considered # special, and renaming them can be a bad thing. # next if /^\./; # and finally, if the file doesn't have any underscores in # it, we can skip it immediately. again, this is for safety: # the rest of our code could operate on the file and rename # it with the same filename, but why waste that processing # power? it's just dirty. it's how bad things happen. # next unless /_/; # at this point, we're assuming that this is a file # we're supposed to be working on. so, we copy the file # name, do our underscore for space conversion, and # issue a rename() from the original name to the new. # again, if something goes wrong with the rename, we # die immediately. this is probably overly cautious. # my $new_name = $_; $new_name=~ s/_/ /g; rename($_, $new_name) or die $!; } And that's the script. For readability, no comments: #!/usr/bin/perl use warnings; use strict; opendir(DIR, .) or die $!; my @files = readdir(DIR); close(DIR); while (@files) { next if -d; next if /^\./; next unless /_/; my $new_name = $_; $new_name=~ s/_/ /g; rename($_, $new_name) or die $!; } It worked fine for him, and we moved on. A few hours later, he asked for a recursive version, and whether that would be hard to do. While I wasn't around to help him out, the weak solution was easy: just move the script into each new directory and run it again. But, there are two other solutions to this new request: the bad one, and the good one. The bad one is to assume the first script is perfect: it's not. It works if you're in the current directory, and the assumptions are that no recursion is necessary. A bad approach to the recursive problem is to start modifying the above script to manually support it: people think hey, I got this working, recursion must be simple as pie, right?!. Usually, they'll end up with something like (pseudo non-working code follows): my DIRECTORIES = start_directory
Re: HOWTO: File Renaming and Directory Recursion
On Thu, Apr 01, 2004 at 07:05:51PM -0500, Morbus Iff wrote: Earlier this morning, a friend of mine asked me for a script that would given a list of files, replace underscores with spaces, to take this: Artist_Name-Track_Name.mp3 and rename it to this: Artist Name-Track Name.mp3 The script was mindlessly simple, and I felt it would be a good HOWTO for the perl beginners crowd, if not to show some good code practices, but also to counteract the . .. .. . controversial HOWTO that had been posted a week or so ago. Certainly, if you find this as misguided as his, complain onlist with better examples, or offlist with anger. The first bit of code I wrote him was below. Save for the additional explanatory comments, it's nearly exact. [ snip ] And that's the script. For readability, no comments: #!/usr/bin/perl use warnings; use strict; opendir(DIR, .) or die $!; my @files = readdir(DIR); close(DIR); while (@files) { Are you sure that's not: for (@files) { ? next if -d; next if /^\./; next unless /_/; my $new_name = $_; $new_name=~ s/_/ /g; rename($_, $new_name) or die $!; } It worked fine for him, and we moved on. A few hours later, he asked for a recursive version, and whether that would be hard to do. While I wasn't around to help him out, the weak solution was easy: just move the script into each new directory and run it again. But, there are two other solutions to this new request: the bad one, and the good one. Here's a third: $ rename 'y/_/ /' **/*(.) That's zsh globbing and rename that used to come with perl. rename is now part of debian, and google tells me it can be found at: http://www.hurontel.on.ca/~barryp/menu-mysql/music_rename-1.12c/rename Though I'll admit that that solution doesn't provide so many opportunities for learning Perl. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: HOWTO: File Renaming and Directory Recursion
On 4/1/2004 7:05 PM, Morbus Iff wrote: # and here is that subroutine. it's nearly exactly # the same as our previous code, only this time, we # move into the directory that contains a file to # be renamed. this is actually a quick hack because # I knew this wouldn't be production-code: a more proper # solution would be to stay where we are in the directory # structure, and give full paths to our rename(). this # would require the help of another module, File::Spec. # find out more with perldoc File::Spec. it's handy. # sub underscores { next if -d $_; next if /^\./; next unless /_/; my $new_name = $_; $new_name=~ s/_/ /g; chdir($File::Find::dir); rename($_, $new_name) or die $!; } Nice work. Just two quick comments. 1) Above, the chdir is not neccesary because File::Find moves through the directory structure unless you specify no_chdir(?). 2) It might be instructive to follow up with one that handles the directory as a parameter; I agree it would have been distracting here, but as a follow-up it would be a good how-to for a common task (incl usage pod also). Again, this is a great example of a good How-To. Regards, Randy. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: HOWTO: File Renaming and Directory Recursion
while (@files) { Are you sure that's not: for (@files) { Yup, for is right. An error in my memory recall. -- Morbus Iff ( evil is my sour flavor ) Technical: http://www.oreillynet.com/pub/au/779 Culture: http://www.disobey.com/ and http://www.gamegrene.com/ icq: 2927491 / aim: akaMorbus / yahoo: morbus_iff / jabber.org: morbus -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Size of dir (with recursion)
Hey list. I'm having a problem reading the size of a directory with recursive directories. The problem is that du -s shows a different bytecount than my program does. Here's my code: #!/usr/gnu/bin/perl -w use File::Find; @ARGV = ('.') unless @ARGV; my $sum = 0; find sub { $sum += -s }, @ARGV; print @ARGV contains $sum bytes\n; 'du' shows a size of ~120 megabytes, while the program shows a size of something that's waaay larger. Any idea why? Jesper Nøhr - decius [EMAIL PROTECTED] Holstebro, Denmark -- http://printf.dk UNIX Administrator, Software Engineer, Geek. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Size of dir (with recursion)
Jesper Noehr wrote: Hey list. Hello, I'm having a problem reading the size of a directory with recursive directories. The problem is that du -s shows a different bytecount than my program does. $ man du NAME du - estimate file space usage SYNOPSIS du [OPTION]... [FILE]... DESCRIPTION Summarize disk usage of each FILE, recursively for direc tories. Here's my code: #!/usr/gnu/bin/perl -w use File::Find; @ARGV = ('.') unless @ARGV; my $sum = 0; find sub { $sum += -s }, @ARGV; print @ARGV contains $sum bytes\n; 'du' shows a size of ~120 megabytes, while the program shows a size of something that's waaay larger. Any idea why? du looks at disk space usage while your program looks at file sizes. If your disk has a block size of 1024 and you have a file that is 10 bytes in size, du will report the amount of space based on the blocks required to store the file, not on the actual size of the file. $ ls -l test.txt -rw-r--r--1 john users 187 Jul 9 11:54 test.txt $ perl -le'print +(lstat shift)[11]' test.txt 4096 $ du -b test.txt 4096test.txt $ du test.txt 4 test.txt John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Size of dir (with recursion)
On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote: Jesper Noehr wrote: Hey list. Hello, I'm having a problem reading the size of a directory with recursive directories. The problem is that du -s shows a different bytecount than my program does. $ man du NAME du - estimate file space usage SYNOPSIS du [OPTION]... [FILE]... DESCRIPTION Summarize disk usage of each FILE, recursively for direc tories. Here's my code: #!/usr/gnu/bin/perl -w use File::Find; @ARGV = ('.') unless @ARGV; my $sum = 0; find sub { $sum += -s }, @ARGV; print @ARGV contains $sum bytes\n; 'du' shows a size of ~120 megabytes, while the program shows a size of something that's waaay larger. Any idea why? du looks at disk space usage while your program looks at file sizes. If your disk has a block size of 1024 and you have a file that is 10 bytes in size, du will report the amount of space based on the blocks required to store the file, not on the actual size of the file. Hmm, I see. $ ls -l test.txt -rw-r--r--1 john users 187 Jul 9 11:54 test.txt $ perl -le'print +(lstat shift)[11]' test.txt 4096 $ du -b test.txt 4096test.txt $ du test.txt 4 test.txt Great example, thanks. You have any idea how I can rehack my program to return what du does? That is, diskspaceusage. John -- Jesper Nøhr - decius [EMAIL PROTECTED] Holstebro, Denmark -- http://printf.dk UNIX Administrator, Software Engineer, Geek. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Size of dir (with recursion)
Jesper Noehr wrote: On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote: $ ls -l test.txt -rw-r--r--1 john users 187 Jul 9 11:54 test.txt $ perl -le'print +(lstat shift)[11]' test.txt 4096 $ du -b test.txt 4096test.txt $ du test.txt 4 test.txt Great example, thanks. You have any idea how I can rehack my program to return what du does? That is, diskspaceusage. As you can see from the perl script above, the twelfth field of stat and lstat is the block size. $ ls -l file.txt -rw-r--r--1 john users 22982 Nov 13 23:28 file.txt $ du -b file.txt 24576 file.txt $ perl -le'$x = shift; $b = (lstat $x)[11]; $s = -s _; print $s , $s + ( $b - ( $s % $b ) ); ' file.txt 22982 24576 John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Size of dir (with recursion)
While you're at it, write a parallel version of du.pl... Modern hard drives do scatter gather, and reading lots (say 10 or so) of dirs' contents' block sizes at a time would be interesting... It would be cool if a parent kept 20 children pre-forked, and only told 10 children at a time to do their work load. The children upon fork would wait for some IPC from the parent, then do their work, then communicate the answer back to the parent, and die. I don't know if pre-forking is necessary to keep 10 children active, but it's something to make the task harder, and make you learn more! If you wanna learn perl, aim at over-engineered spaghetti. Give yourself a task fit for a mentally insane perl monk, and then you can say you've been to hell and back. Then repeat... On Mon, 2003-12-29 at 15:51, John W. Krahn wrote: Jesper Noehr wrote: On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote: $ ls -l test.txt -rw-r--r--1 john users 187 Jul 9 11:54 test.txt $ perl -le'print +(lstat shift)[11]' test.txt 4096 $ du -b test.txt 4096test.txt $ du test.txt 4 test.txt Great example, thanks. You have any idea how I can rehack my program to return what du does? That is, diskspaceusage. As you can see from the perl script above, the twelfth field of stat and lstat is the block size. $ ls -l file.txt -rw-r--r--1 john users 22982 Nov 13 23:28 file.txt $ du -b file.txt 24576 file.txt $ perl -le'$x = shift; $b = (lstat $x)[11]; $s = -s _; print $s , $s + ( $b - ( $s % $b ) ); ' file.txt 22982 24576 John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/ http://learn.perl.org/first-response
Re: Recursion
James Edward Gray II wrote: On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote: Jeff Westman wrotenews:[EMAIL PROTECTED] Hi, I've never liked recursion but of course there are times where it is needed. I'm not sure I would say recursion is needed, but it sure makes some things simpler. I've never met a recursive function I couldn't rewrite iteratively though, often with some pain, of course. Recursion can always be eliminated by hard-coding the stacking of context variables that the compiler provides and using a loop instead of a recursive call. In fact this is exactly what File::Find itself does. But recursive code will almost always allow a better expression of an algorithm than the hammer and nails technique. Cheers, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
Steve Grazzini wrote: On Sun, Nov 02, 2003 at 05:32:35PM -0600, James Edward Gray II wrote: On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote: sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; I'm not sure this grep() is what you meant it to be. It selects any file containing a non-dot character, as written. Right. The files to skip are . (this directory) and .. (the parent directory). Rob's solution also skips ..., though, so it's not perfect. I probably would have preferred grep /^[^.]/, ..., which get all files starting with a non-dot character. I believe that's a little more typical UNIX behavior. That's fine if you *want* to skip the dotfiles. But you *always* skip . and ... More robust code will also check for cycles, but since File::Find does all this already, it's usually better just to use the module. Hi Steve. Cycles are eliminated by discarding links and printing only directories and regular files. /R -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
R. Joseph Newton wrote: Rob Dixon wrote: Jeff Westman wrotenews:[EMAIL PROTECTED] I've never liked recursion but of course there are times where it is needed. I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. Pretty basic, but I have a total mental block using recursion. Any quick help or tips would be appreciated. File::Find would do it for you, but the recursion is very simple really: HI Rob, This is great, but could use just a bit of textual explanation: use strict; use warnings; printdir('/usr'); sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; closedir DIR; foreach (map $dir/$_, @dirs) { if (-d) { # recursive case printdir($_); } elsif (-f _) { print $_, \n; #stopping case } } } HTH, Rob Doesn't take much. Recursion is, as you say, fairly simple in its essence. I just thought that it would be good to explicitly point out the need for a stopping case to prevent infinite recursion. I'm not sure the idea of a 'stopping case' is relevant here. That is more useful when recursion is used to evaluate one function in terms of another simpler one, as in the classic sub factorial { my $x = shift; $x 1 ? $x * factorial($x - 1) : 1; } when there must be a case where the function is no longer reduceable and has a value defined non-recursively. Scanning directory recursively works because the data structure is recursive, and cannot fail to terminate as long as there are no loops in the data (which is true here since the code ignores symbolic links). Cheers, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Monday, November 3, 2003, at 03:43 AM, Rob Dixon wrote: Recursion can always be eliminated by hard-coding the stacking of context variables that the compiler provides and using a loop instead of a recursive call. In fact this is exactly what File::Find itself does. But recursive code will almost always allow a better expression of an algorithm than the hammer and nails technique. For some definition of better meaning easier to understand, but certainly not faster, right? ;) I agree with Rob that recursion is usually prettier. It has very real limits though, that iteration can often extend greatly. Also, if you're ever looking for more speed, start with unrolling recursions, trust me. James -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote: Steve Grazzini wrote: That's fine if you *want* to skip the dotfiles. But you *always* skip . and ... More robust code will also check for cycles, but since File::Find does all this already, it's usually better just to use the module. Cycles are eliminated by discarding links and printing only directories and regular files. The problem is that -d $path will return true if $path is a symlink to a directory. -- Steve -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
Steve Grazzini wrote: On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote: Steve Grazzini wrote: That's fine if you *want* to skip the dotfiles. But you *always* skip . and ... More robust code will also check for cycles, but since File::Find does all this already, it's usually better just to use the module. Cycles are eliminated by discarding links and printing only directories and regular files. The problem is that -d $path will return true if $path is a symlink to a directory. Thanks Steve, but are you certain? I can't test it here. As far as I know this behaviour isn't documented anywhere. Anybody? Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Mon, Nov 03, 2003 at 11:16:02PM -, Rob Dixon wrote: Steve Grazzini wrote: On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote: Steve Grazzini wrote: That's fine if you *want* to skip the dotfiles. But you *always* skip . and ... More robust code will also check for cycles, but since File::Find does all this already, it's usually better just to use the module. Cycles are eliminated by discarding links and printing only directories and regular files. The problem is that -d $path will return true if $path is a symlink to a directory. Thanks Steve, but are you certain? I can't test it here. As far as I know this behaviour isn't documented anywhere. Anybody? Steve is right (just for a change). I don't know that this is documented anywhere specifically. Possibly the closest is in perldoc -f stat (at the end on recent perls) and man 2 stat (on systems that have that). -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Tue, Nov 04, 2003 at 12:45:58AM +0100, Paul Johnson wrote: On Mon, Nov 03, 2003 at 11:16:02PM -, Rob Dixon wrote: Steve Grazzini wrote: The problem is that -d $path will return true if $path is a symlink to a directory. Thanks Steve, but are you certain? I can't test it here. As far as I know this behaviour isn't documented anywhere. Steve is right (just for a change). Yeah, I try to mix a few good answers in with the nonsense... I don't know that this is documented anywhere specifically. Possibly the closest is in perldoc -f stat (at the end on recent perls) and man 2 stat (on systems that have that). It's one of those things that you can't find until you already know about it. The idea is that (given a UNIX-centric view of the world) absolutely everything follows symlinks, and only exceptions to this rule need to be documented. % perldoc -f -X ... (This doesn't work with -t, and you need to remember that lstat() and -l will leave values in the stat structure for the symbolic link, not the real file.) % perldoc -f lstat lstat FILEHANDLE lstat EXPR lstat Does the same thing as the stat function (including setting the special _ filehandle) but stats a symbolic link instead of the file the symbolic link points to. There's also some good stuff in the description of the follow options for (cough!) File::Find. -- Steve -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
Jeff Westman wrotenews:[EMAIL PROTECTED] Hi, I've never liked recursion but of course there are times where it is needed. I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. Pretty basic, but I have a total mental block using recursion. Any quick help or tips would be appreciated. Hi Jeff. File::Find would do it for you, but the revursion is very simple really: use strict; use warnings; printdir('/usr'); sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; closedir DIR; foreach (map $dir/$_, @dirs) { if (-d) { printdir($_); } elsif (-f _) { print $_, \n; } } } HTH, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
Rob Dixon wrote: Jeff Westman wrotenews:[EMAIL PROTECTED] Hi, I've never liked recursion but of course there are times where it is needed. I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. Pretty basic, but I have a total mental block using recursion. Any quick help or tips would be appreciated. Hi Jeff. File::Find would do it for you, but the revursion is very simple really: HI Rob, This is great, but could use just a bit of textual explanation: use strict; use warnings; printdir('/usr'); sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; closedir DIR; foreach (map $dir/$_, @dirs) { if (-d) { # recursive case printdir($_); } elsif (-f _) { print $_, \n; #stopping case } } } HTH, Rob Doesn't take much. Recursion is, as you say, fairly simple in its essence. I just thought that it would be good to explicitly point out the need for a stopping case to prevent infinite recursion. Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote: File::Find would do it for you, but the revursion is very simple really: use strict; use warnings; printdir('/usr'); sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; I'm not sure this grep() is what you meant it to be. It selects any file containing a non-dot character, as written. I probably would have preferred grep /^[^.]/, ..., which get all files starting with a non-dot character. I believe that's a little more typical UNIX behavior. James -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote: Jeff Westman wrotenews:[EMAIL PROTECTED] Hi, I've never liked recursion but of course there are times where it is needed. I'm not sure I would say recursion is needed, but it sure makes some things simpler. I've never met a recursive function I couldn't rewrite iteratively though, often with some pain, of course. Hi Jeff. File::Find would do it for you, but the revursion is very simple really: use strict; use warnings; printdir('/usr'); sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; closedir DIR; foreach (map $dir/$_, @dirs) { if (-d) { printdir($_); } elsif (-f _) { print $_, \n; } } } # or iteratively... sub printdir { my @dirs = (shift); while (@dirs) { my $dir = shift @dirs; opendir DIR, $dir or die Directory error: $!; my @new_dirs = grep /^[^.]/, readdir DIR; closedir DIR; foreach (map $dir/$_,@new_dirs) { if (-d) { push @dirs, $_; } elsif (-f _) { print $_\n; } } } } James -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Sun, Nov 02, 2003 at 05:32:35PM -0600, James Edward Gray II wrote: On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote: sub printdir { my $dir = shift; opendir DIR, $dir or die $!; my @dirs = grep /[^.]/, readdir DIR; I'm not sure this grep() is what you meant it to be. It selects any file containing a non-dot character, as written. Right. The files to skip are . (this directory) and .. (the parent directory). Rob's solution also skips ..., though, so it's not perfect. I probably would have preferred grep /^[^.]/, ..., which get all files starting with a non-dot character. I believe that's a little more typical UNIX behavior. That's fine if you *want* to skip the dotfiles. But you *always* skip . and ... More robust code will also check for cycles, but since File::Find does all this already, it's usually better just to use the module. -- Steve -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Recursion
Hi, I've never liked recursion but of course there are times where it is needed. I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. Pretty basic, but I have a total mental block using recursion. Any quick help or tips would be appreciated. Thanks in advance, Jeff __ Do you Yahoo!? Exclusive Video Premiere - Britney Spears http://launch.yahoo.com/promos/britneyspears/ -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Sat, Nov 01, 2003 at 05:20:39PM -0800, Jeff Westman wrote: I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. use File::Find; find sub { print $File::Find::name\n if -d }, '/'; -- Steve -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Recursion
On Sat, 2003-11-01 at 20:20, Jeff Westman wrote: Hi, I've never liked recursion but of course there are times where it is needed. I have a simple task that I am trying to do. Basically, I just want to list out my directories on disk, and then chdir to each one, print it out, and so on. Pretty basic, but I have a total mental block using recursion. Any quick help or tips would be appreciated. Thanks in advance, Jeff __ Do you Yahoo!? Exclusive Video Premiere - Britney Spears http://launch.yahoo.com/promos/britneyspears/ I'm rusty on recursion too, but here are some resources that explain it on Perlmonks.com http://www.perlmonks.com/index.pl?node_id=101801 http://www.perlmonks.com/index.pl?node_id=41634 Also, if you're parsing directories and files, Randal has two awesome columns on this very subject http://www.stonehenge.com/merlyn/LinuxMag/col45.html http://www.stonehenge.com/merlyn/LinuxMag/col46.html Hope this helps, Kevin -- Kevin Old [EMAIL PROTECTED] -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
recursion and memory use... a lot of memory use.
I have this program that recurses through a directory structure building Default.htm files. The idea here was to quickly generate a bunch of these things to replace the default index listing you normally see. The part that's giving me trouble is the navbar that should have a nested structure like... Food Fruit Apples Oranges Kiwi Vegetables Coffee Critters Cars Rocks So that if you are in /DocRoot/Food/Fruit you would see the above on the left all properly linked yada yada. The code I've pasted in does this just fine (I've removed a bunch of stuff to focus on the real problem) but only on small directory structures. When I run it on something with 10 directory levels, 3 or 4 subdirectories in each one, 20-30 files in each one, it zips along for a few seconds then grinds to a halt, consumes all my physical memory and begins swapping like mad. I changed things around to not use the joinLists() function and to have buildIndices() call itself rather than have getLinks call it and it works fine. But I don't know why, hence the posting. Anyone feel like tackling this? Thanks! Peter C. -- #! perl use strict; use warnings; use File::Copy; use vars ('$rootDir'); #=== # Main #=== my $baseURL = engweb; $rootDir = d:/inetpub/wwwroot/$baseURL; buildIndices($rootDir, /$baseURL) or die (failed trying to build $rootDir\n); exit 0; #=== # Functions #=== #--- # buildIndices($dir, $parentLinks) # # This function takes a document directory and builds the # Default.htm file for it. # sub buildIndices { my ($dir, $url, $parentLinks) = @_; #$parentLinks is an array ref. my $cwd = (split /\\|\//, $dir)[-1]; print currently working on $dir\n; local $ = \n; #Set the list seperator to a new line. #All we want is 2 things, a directory and an html file. #Is that too much to ask for? copy ($rootDir\\Default.htm, $dir\\Default.htm) unless -T $dir\\Default.htm; unless (-d $dir and -T $dir\\Default.htm) { print $dir is not a directory\n unless -d $dir; print We couldn't put the Default.htm file in $dir\n unless -T $dir\\Default.htm; return 0; } my @curLinks = getLinks($dir, $url, $parentLinks); #links should have a bunch of 'a href...' strings #if we were given a parentLinks array splice these two together. # if there were no subdirectories or files splice in an anonymous # array that Just says EMPTY my @links = ($parentLinks and $cwd) ? joinLists (@curLinks ? \@curLinks : [DIV STYLE=\margin:10\, Empty, /DIV], $parentLinks, $cwd) : @curLinks; #there's just an inplace edit here... # #... return 1; #one is good } #--- # getLinks($dir) # # loop through the directory entries and build a bunch of 'a href...' # strings and stuff them in an array. If the entry is a directory call # buildIndices($ent) on it. # sub getLinks { my ($dir, $url, $parentLinks) = @_; my @subDirs; my @links = (); my $link; my $ent; #a thing for iterating over directory entries my $cwd = (split /\\|\//, $dir)[-1]; opendir (DH, $dir) or logItAndDie(Can't open the directory $rootDir, status=$!\n); while (defined ($ent = readdir(DH))) { next if $ent =~ /^\./; #skip things with leading '.' if (-d $dir/$ent) { #Add some spaces. push @links, a href=\$url/$ent/Default.htm\$ent/abr; push @subDirs, $dir/$ent; #to be used in calls to buildIndices } elsif ($ent =~ /\.(htm|html|jsp|doc)$/) { if (!($ent =~ /Default/)) { # Skip the Default files push @links, a href=\$url/$ent\$ent/abr; } } } closedir(DH); if (@links) { unshift @links, DIV STYLE=\margin:10\; push @links, /DIV; } my @completeLinks = ($cwd and $parentLinks) ? joinLists (\@links, $parentLinks, $cwd) : @links; for (@subDirs) { buildIndices($_, $url/ . (split /\\|\//)[-1],