Re: subroutine references

2007-08-27 Thread Jenda Krynicky
From: "Mr. Shawn H. Corey" <[EMAIL PROTECTED]>
> Dr.Ruud wrote:
> >> Why do people who write these books have exercises of little
> >> practical value? 
> > 
> > An exercise needs to be educational. 
> 
> I have worked in programming for 25 years and during that time I have
> never use a closure and have never seen one used.  I may be harsh in
> my definitions but to me something that is never used is useless. 
> Teaching people to do useless things is not educational. 

Y'knaw son, I've been hacking trees down all my life with this here 
hack and its a good hack, got it from my late father, I did. And I've 
never user this what you call chainsaw and have never seen one user. 
I may be harsh, y'know, but if you ask me, something that is never 
used is useless. So go away with your chainsaw and let me go on with 
my hacking. I've got this tree to cut down and I havn't got whole day 
to do it.

> >> closure introduce another layer of compile/run to the program.  They
> >> should be avoided.   
> > 
> > Why would a "closure introduce another layer of compile/run"? 
> > A closure carries an environment, so just call it an object. 
> > 
> 
> Dealing with a closure has two phases.  A phases when its created
> (compiled phase) and one when it's executed (run phase).  When you
> write a closure you have to keep the two phases in mind (and
> separate). 

I think I know what you mean, though the choice of words is 
unfortunate.

 
> For example, in the OP's problem there are three parameters: the start
> time, the stop time, and the staring directories.  Since it doesn't
> make much sense to separate the start ans stop times, I shall treat
> them as a data set called times.  There are four ways to distribute
> them: 
> 
> 1. All are parameters to the closure generator.  In this case, the
> closure is not very flexible.  What it can tell are if a file has been
> modified between its runs. 
> 
> 2. The times are closure-generator parameters and the starting
> directories are closure parameters.  This gives a closure that can
> look at different directories but in the same time interval. 
> 
> 3. The starting directories are closure-generator parameters and the
> times are closure ones.  This gives a closure that looks at the same
> directories but with different time intervals. 
> 
> 4. All are parameters are closure ones.  This gives a closure that is
> very flexible but is little different from a common sub. 

So you proved that this exercise is not the best case for the usage 
of closures. I'd agree on that one. BTW, the 2. and 3. are 
(especially the way you explain them) perfect examples of function 
currying. Another thing you've never user nor seen used. The Perl5 
way of function parameter handling doesn't allow for nice support for 
currying though.

> The problem with closures is that you have to write them and their
> generators at the same time.  So you have to keep two different phases
> in mind, the compile phase and the run phase, while remembering what
> parameters belong to which phase. 

Well, I would not call that a problem. Let me give you a differet 
example of a closure.

Imagine you are writing a GUI. What you need to do is to specify what 
to do when this button is clicked, that button is clicked, ...

There are basically three ways to do that. (Three and half.)

First, Visual Basic, use a naming convention:
Sub ButtonName_OnClick
  SomeObject.Frobnicate
End Sub

Sub OtherButtonName_OnClick
  OtherObject.Frobnicate
End Sub


Second, C++ (I believe), use function pointers
hResult ButtonName_OnClick() {
  SomeObject.Frobnicate();
}
hResult OtherButtonName_OnClick() {
  OtherSomeObject.Frobnicate();
}
...
TheWindow.Buttons('ButtonName).AttachHandler(&ButtonName_OnClick);
TheWindow.Buttons('OtherButtonName).AttachHandler(&OtherButtonName_OnC
lick);

Second and half, C#, similar to C++ except that instead of 
&ButtonName_OnClick you have to instantiate the right delegate 
object.

In both (all) those cases you have to NAME the functions and you end 
up with lots of functions that look the same. Just lovely.


Or you can use closures ... the simple ones without a generator:

 $window->addButton(-name => 'ButtonName', -title => 'Sumfin', -
onClick => sub {$someObject->frobnicate()});
 # and the $someObject does not have to be global!!!

or if the subroutine is more complex and used more times with 
different objects:

sub frobincareObj {
  my $obj = shift;
  return sub {
do this
do that
$obj->prepare( something);
$obj->frobnicate( some params);
...
  }
}
...
 $window->addButton(-name => 'ButtonName', -title => 'Sumfin', 
   -onClick => frobnicateObj($someObject));
 $window->addButton(-name => 'OtherButtonName', -title => 'Sumfin 2', 
   -onClick => frobnicateObj($someObject));


You could of course do something like this with objects. That is if 
the "type system" doesn't prevent that. Something like:

class callFrobnicate : thisIsNotAClosure {
  frobnicable* the_obj;
  callFrobnic

Re: subroutine references

2007-08-27 Thread Jenda Krynicky
From:   Chris <[EMAIL PROTECTED]>
> Ok, if anyone is interested, here is my answer:
> 
> #!/usr/bin/perl -w
> 
> # Testing code for Exercise 6-1. Your task is to write the sub
> # gather_mtime_between.
> 
> use strict;
> 
> use File::Find;
> use Time::Local;
> 
> my ($start, $stop) = @_;
> my @starting_directories = @_;
> my @found_items;
> 
> sub gather_mtime_between {
>   return (
>   sub {
>   my $timestamp = (stat $_)[9];
>   if ($start <= $timestamp && $timestamp <= $stop){
>   push @found_items, $File::Find::name;
>   } else {
>   print "No file modified between $start and 
> $stop in
> $File::Find::dir\n";
>   }
>   },
>   sub { return @found_items }
>   )
> }


If you do it this way there is no point in returning the subroutine 
references in the first place. You are using global variables here 
(even though you declare them with my).

You can't call the gather_mtime_between() twice and get two unrelated 
pairs of functions. You should move the declarations INTO the sub 
gather_mtime_between(). And fix the assignment from @_.

The exercise is a bit awkward though.

Jenda
= [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-27 Thread Peter Scott
On Sun, 26 Aug 2007 13:04:48 -0400, Mr. Shawn H. Corey wrote:
> I have worked in programming for 25 years and during that time I have
> never use a closure and have never seen one used.  

Boggle.  I don't think any program I write these days doesn't have one. 
They're the most convenient way of restricting static variable scope.
 
> Dealing with a closure has two phases.  A phases when its created
> (compiled phase) and one when it's executed (run phase).  When you write a
> closure you have to keep the two phases in mind (and separate).

Ah, I think the problem is your definition of 'closure'.   I believe
you're confining it to the function factory:

  sub incr { my $x = shift; return sub { $x++ } }

In fact this is also a closure:

{ # Naked block
  my $fh; # Scoped to this block

  sub write_log {
open $fh, '>', $LOGFILE or die $! unless $fh;
print $fh @_;
  }
}

write_log() is closed on $fh.

-- 
Peter Scott
http://www.perlmedic.com/
http://www.perldebugged.com/


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread Chas Owens
On 8/26/07, Mr. Shawn H. Corey <[EMAIL PROTECTED]> wrote:
> Dr.Ruud wrote:
> >> Why do people who write these books have exercises of little
> >> practical value?
> >
> > An exercise needs to be educational.
>
> I have worked in programming for 25 years and during that time I have never 
> use a
> closure and have never seen one used.  I may be harsh in my definitions but 
> to me
> something that is never used is useless.  Teaching people to do useless 
> things is
> not educational.
snip

So, you have never used sort, map, grep, File::Find::find, or any of
the other Higher Order functions?  They all take a code block or
anonymous function that makes use of closures.  Oh, and in my ten
years of coding experience I have only been consciously using them for
the last six (when I moved from mostly ESQL/C and 4GL to mostly Perl).

snip
> Objects can do the same things as closures, which is store and hide data,
> but don't have this problem of having to keep in mind two phases of the same 
> code.
snip

Objects in Perl do not do a very good job of data hiding.  In fact,
one of the few ways to actually hide data in is to use closures (see
perldoc perltoot).

You seem to not understand closures or what they are useful for.  I
would suggest running out and getting Higher Order Perl.  It will make
you a better programmer (even if you are a good programmer now).

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread brian d foy
In article <[EMAIL PROTECTED]>, Mr. Shawn H. Corey
<[EMAIL PROTECTED]> wrote:

> Chris wrote:

> > I'm working on yet another exercise from Intermediate Perl.  I've been
> > given a script that searches for files that fall between a two
> > timestamps. 

> Why do people who write these books have exercises of little practical value?

Exercises are a tough thing. The trick is to:

   * find something that demonstrates the feature being discussed
   * doesn't need features you haven't shown yet
   * isn't saddled with a unfamiliar problem domain 
   * can be completed with what the student likely has already installed
   * is limited enough that it can be completed in a reasonable time
   * works for the entire audience

Anything with "practical value" is likely to not actually be very
practical to someone else. In this case, sysadmins may think the
exercise is very practical, but bio-informaticists may not. 

However, practicality is the wrong way to learn. We don't intend to
teach anyone how to do a specific task. We're teaching the tools people
can use to solve all sorts of different tasks. Learn to use the tool
and you can do a lot. Learn a task, and that's all you can do.

Please feel free to send me suggestions for different exercises for the
second edition, or point me toward the book that you wrote so I can
look at your exercises to see how I might make things more practical.
:)

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread Rob Dixon

Mr. Shawn H. Corey wrote:

Dr.Ruud wrote:

Why do people who write these books have exercises of little
practical value? 


An exercise needs to be educational. 


I have worked in programming for 25 years and during that time I have 
never use a closure and have never seen one used.  I may be harsh in my 
definitions but to me something that is never used is useless.  Teaching 
people to do useless things is not educational.


Sorry Shawn, but if you're going to claim that anything you haven't seen in
your illustrious 25-year career is useless than the rest of your post isn't
worth reading.

Rob

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread Randal L. Schwartz
> "Shawn" == "Mr Shawn H Corey" <[EMAIL PROTECTED]> writes:

Shawn> Oh, I get it.  When I said 25 years, you thought that I meant 25 years
Shawn> with Perl.

No.

Shawn>   Sorry, about the confusion.

No confusion.

Shawn> I have programmed in many different languages and have never seen a
Shawn> closure.

Then you've used a different set of languages from what I have.

Shawn>   All programming languages are Turing complete, so it is possible to
Shawn> create a closure in any language;

The second part doesn't follow from the first.  Perhaps you don't understand
"closure" well enough to be commenting on it.

Shawn>  meaning that if they were useful, they would appear more
Shawn> often.

Also an unsubstantiated conclusion.  You're just leaping from one thing to the
next here, and getting deeper in pure speculation instead of justified facts.

Shawn>   And I have never seen one (except in academia).

Then you've had a pretty narrow bit of experience for being around for "25
years".

Shawn> And OK, you're not mean; you just have a mean sense of humour.

No, I don't think it's humor.  It's just calling BS where I see it, like the
message I'm reply to here.  People may laugh, but the intent is communication.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> 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/




Re: subroutine references

2007-08-26 Thread Mr. Shawn H. Corey

Randal L. Schwartz wrote:

"Shawn" == Shawn H Corey <[EMAIL PROTECTED]> writes:


Shawn> Why do you include an insult with every thing you post?

I don't think I do.  I was only making fun of your claim, since you made the
claim.  Why did you include "25 years"?  It just sets you up for a fall. :)


Oh, I get it.  When I said 25 years, you thought that I meant 25 years with 
Perl.  Sorry, about the confusion.  I have programmed in many different 
languages and have never seen a closure.  All programming languages are Turing 
complete, so it is possible to create a closure in any language; meaning that 
if they were useful, they would appear more often.  And I have never seen one 
(except in academia).

And OK, you're not mean; you just have a mean sense of humour.


--
Just my 0.0002 million dollars worth,
 the "legendary" Shawn

"For the things we have to learn before we can do them, we learn by doing them."
 Aristotle

"If you think Terrans are comprehensible, you don't understand them."
 Great Fang Talphon

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread Randal L. Schwartz
> "Shawn" == Shawn H Corey <[EMAIL PROTECTED]> writes:

Shawn> Why do you include an insult with every thing you post?

I don't think I do.  I was only making fun of your claim, since you made the
claim.  Why did you include "25 years"?  It just sets you up for a fall. :)

Shawn> BTW, what legends do you have on me? (web links preferred) (and nothing
Shawn> from stonehenge.com, independent sources only).  Do they make me out as
Shawn> mean as you?

Again, I don't think I've been mean.  But I will knock the wind out of any
air-filled claim, and you made one here.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> 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/




Re: subroutine references

2007-08-26 Thread Mr. Shawn H. Corey

Randal L. Schwartz wrote:

Think of closures as "variables that hold behavior".  Sure, maybe you've never
needed that in your legendary 25 years in the industry, but I've used it
*frequently* in my 30 years. :)



Why do you include an insult with every thing you post?

BTW, what legends do you have on me? (web links preferred) (and nothing from 
stonehenge.com, independent sources only).  Do they make me out as mean as you?


--
Just my 0.0002 million dollars worth,
 Shawn

"For the things we have to learn before we can do them, we learn by doing them."
 Aristotle

"If you think Terrans are comprehensible, you don't understand them."
 Great Fang Talphon

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-26 Thread Randal L. Schwartz
> ""Mr" == "Mr Shawn H Corey" <[EMAIL PROTECTED]> writes:

Mr> Objects can do the same things as closures, which is store and hide data,
Mr> but don't have this problem of having to keep in mind two phases of the
Mr> same code.

But objects have fixed code with variable data.  Closures can have variable
code with variable data, including user-specified behavior passed in to a
constructor or a mutator.  So, yes, objects can do *some* of the things that
closures do, but not all.

Think of closures as "variables that hold behavior".  Sure, maybe you've never
needed that in your legendary 25 years in the industry, but I've used it
*frequently* in my 30 years. :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> 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/




Re: subroutine references

2007-08-26 Thread Mr. Shawn H. Corey

Dr.Ruud wrote:

Why do people who write these books have exercises of little
practical value? 


An exercise needs to be educational. 


I have worked in programming for 25 years and during that time I have never use 
a closure and have never seen one used.  I may be harsh in my definitions but 
to me something that is never used is useless.  Teaching people to do useless 
things is not educational.





closure introduce another layer of compile/run to the program.  They
should be avoided.   


Why would a "closure introduce another layer of compile/run"? 
A closure carries an environment, so just call it an object. 



Dealing with a closure has two phases.  A phases when its created (compiled 
phase) and one when it's executed (run phase).  When you write a closure you 
have to keep the two phases in mind (and separate).

For example, in the OP's problem there are three parameters: the start time, 
the stop time, and the staring directories.  Since it doesn't make much sense 
to separate the start ans stop times, I shall treat them as a data set called 
times.  There are four ways to distribute them:

1. All are parameters to the closure generator.  In this case, the closure is 
not very flexible.  What it can tell are if a file has been modified between 
its runs.

2. The times are closure-generator parameters and the starting directories are 
closure parameters.  This gives a closure that can look at different 
directories but in the same time interval.

3. The starting directories are closure-generator parameters and the times are 
closure ones.  This gives a closure that looks at the same directories but with 
different time intervals.

4. All are parameters are closure ones.  This gives a closure that is very 
flexible but is little different from a common sub.

The problem with closures is that you have to write them and their generators 
at the same time.  So you have to keep two different phases in mind, the 
compile phase and the run phase, while remembering what parameters belong to 
which phase.

Objects can do the same things as closures, which is store and hide data, but 
don't have this problem of having to keep in mind two phases of the same code.


--
Just my 0.0002 million dollars worth,
 Shawn

"For the things we have to learn before we can do them, we learn by doing them."
 Aristotle

"If you think Terrans are comprehensible, you don't understand them."
 Great Fang Talphon

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Dr.Ruud
Chris schreef:

> #!/usr/bin/perl -w

Toss the -w, and insert a "use warnings;".


> my ($start, $stop) = @_;
> my @starting_directories = @_;

This doesn't do what I think that you think it does.


> my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;

Is the start/top related to today?
What if you want the files of the 2-week-period between 3 weeks ago and
1 week ago?

-- 
Affijn, Ruud

"Gewoon is een tijger."


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Chris
Ok, if anyone is interested, here is my answer:

#!/usr/bin/perl -w

# Testing code for Exercise 6-1. Your task is to write the sub
# gather_mtime_between.

use strict;

use File::Find;
use Time::Local;

my ($start, $stop) = @_;
my @starting_directories = @_;
my @found_items;

sub gather_mtime_between {
return (
sub {
my $timestamp = (stat $_)[9];
if ($start <= $timestamp && $timestamp <= $stop){
push @found_items, $File::Find::name;
} else {
print "No file modified between $start and 
$stop in
$File::Find::dir\n";
}
},
sub { return @found_items }
)
}

my $target_dow = 5; # Sunday is 0, Monday is 1, ...
@starting_directories = ("/home/io/chris_perl/int_perl/");

my $seconds_per_day = 24 * 60 * 60;
my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;
$start = timelocal(0, 0, 0, $day, $mon, $yr);   # midnight today
while ($dow != $target_dow) {
  # Back up one day
  $start -= $seconds_per_day;   # hope no DST! :-)
  if (--$dow < 0) {
$dow += 7;
  }
}
$stop = $start + $seconds_per_day;

my($gather, $yield)  = gather_mtime_between($start, $stop);
find($gather, @starting_directories);
my @files = $yield->();

for my $file (@files) {
  my $mtime = (stat $file)[9];  # mtime via slice
  my $when = localtime $mtime;
  print "$when: $file\n";
}

I think my main problem was that I didn't grasp how File::Find works.
After I read the docs on CPAN, the solution came together.


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Dr.Ruud
Shawn schreef:
> Chris:

>> I'm working on yet another exercise from Intermediate Perl.  I've
>> been given a script that searches for files that fall between a two
>> timestamps.  For the exercise, I am supposed to write the
>> gather_mtime_between subroutine that will return two references to
>> two subroutines.  One will use File::Find that will find the files
>> that were modified between the two timestamps.  The other function
>> should return a list of the found items.
>> 
> 
> Why do people who write these books have exercises of little
> practical value? 

An exercise needs to be educational. 


> closure introduce another layer of compile/run to the program.  They
> should be avoided.   

Why would a "closure introduce another layer of compile/run"? 
A closure carries an environment, so just call it an object. 

-- 
Affijn, Ruud

"Gewoon is een tijger."

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Mr. Shawn H. Corey

Mr. Shawn H. Corey wrote:

Chris wrote:

I'm working on yet another exercise from Intermediate Perl.  I've been
given a script that searches for files that fall between a two
timestamps.  For the exercise, I am supposed to write the
gather_mtime_between subroutine that will return two references to two
subroutines.  One will use File::Find that will find the files that
were modified between the two timestamps.  The other function should
return a list of the found items.



Why do people who write these books have exercises of little practical 
value?


When you say return two sub references you do mean two anonymous subs, 
not just references to two conventional subs?



use strict;

use File::Find;
use Time::Local;

sub gather_mtime_between {


 my @found_items = ();


return (
sub {


 my $start = shift @_;
 my $stop  = shift @_;
 my @starting_directories = @_;


# Oops, don't add this statement.  Sorry, about that.

 my @found_items = ();






foreach my $filename(my @file_list){
my $timestamp = (stat $filename)[9];
if (my $start <= $timestamp <= my $stop){


if( $start <= $timestamp && $timestamp <= $stop ){


push @found_items, $filename;
}
}
},


# Note that this sub does not use anything from File::Find.


sub { return @found_items };
)
}


Incorporating File::Find into them is still up to you.  Hint:
 find( sub { ... }, @starting_directories );

This exercise creates what is called a closure.  But any closure can be 
replaced by an object.  Objects are easier to understand because closure 
introduce another layer of compile/run to the program.  They should be 
avoided.





--
Just my 0.0002 million dollars worth,
 Shawn

"For the things we have to learn before we can do them, we learn by doing them."
 Aristotle

"If you think Terrans are comprehensible, you don't understand them."
 Great Fang Talphon

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Mr. Shawn H. Corey

Chris wrote:

I'm working on yet another exercise from Intermediate Perl.  I've been
given a script that searches for files that fall between a two
timestamps.  For the exercise, I am supposed to write the
gather_mtime_between subroutine that will return two references to two
subroutines.  One will use File::Find that will find the files that
were modified between the two timestamps.  The other function should
return a list of the found items.



Why do people who write these books have exercises of little practical value?

When you say return two sub references you do mean two anonymous subs, not just 
references to two conventional subs?


use strict;

use File::Find;
use Time::Local;

sub gather_mtime_between {


 my @found_items = ();


return (
sub {


 my $start = shift @_;
 my $stop  = shift @_;
 my @starting_directories = @_;
 my @found_items = ();


foreach my $filename(my @file_list){
my $timestamp = (stat $filename)[9];
if (my $start <= $timestamp <= my $stop){


if( $start <= $timestamp && $timestamp <= $stop ){


push @found_items, $filename;
}
}
},


# Note that this sub does not use anything from File::Find.


sub { return @found_items };
)
}


Incorporating File::Find into them is still up to you.  Hint:
 find( sub { ... }, @starting_directories );

This exercise creates what is called a closure.  But any closure can be 
replaced by an object.  Objects are easier to understand because closure 
introduce another layer of compile/run to the program.  They should be avoided.


--
Just my 0.0002 million dollars worth,
 Shawn

"For the things we have to learn before we can do them, we learn by doing them."
 Aristotle

"If you think Terrans are comprehensible, you don't understand them."
 Great Fang Talphon

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: subroutine references

2007-08-25 Thread Tom Phoenix
On 8/25/07, Chris <[EMAIL PROTECTED]> wrote:

> if (my $start <= $timestamp <= my $stop){

Until Perl 6, you have to break down chain comparisons like this into
separate comparisons, usually joined with 'and':

if ($start <= $timestamp and $timestamp <= $stop) { ... }

But the real problem is the my() function, which should rarely if ever
appear within a conditional expression. Use my() to declare lexical
variables at the start of their scope. The scope of a lexical variable
is the part of the program in which these names can be used for these
variables. The scope continues until the end of the smallest enclosing
block or file.

In this case, you need to declare your variables outside the scope of
the subroutine, since you don't want them to be available only within
the sub. Ideally, they should be declared in the smallest possible
scope that needs them. I think you want them to be declared near the
start of gather_mtime_between, using the subroutine parameters in the
@_ variable:

  my($start, $stop) = @_; # sub parameter list

That is to say, each invocation of gather_mtime_between would be given
its own $start and $stop values. It can then return closures, which
are subroutines which use those persistant variables from a larger
scope.

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




subroutine references

2007-08-25 Thread Chris
I'm working on yet another exercise from Intermediate Perl.  I've been
given a script that searches for files that fall between a two
timestamps.  For the exercise, I am supposed to write the
gather_mtime_between subroutine that will return two references to two
subroutines.  One will use File::Find that will find the files that
were modified between the two timestamps.  The other function should
return a list of the found items.

use strict;

use File::Find;
use Time::Local;

sub gather_mtime_between {
return (
sub {
foreach my $filename(my @file_list){
my $timestamp = (stat $filename)[9];
if (my $start <= $timestamp <= my $stop){
push @found_items, $filename;
}
}
},
sub { return @found_items };
)
}

my $target_dow = 1; # Sunday is 0, Monday is 1, ...
my @starting_directories = (".");

my $seconds_per_day = 24 * 60 * 60;
my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;
my $start = timelocal(0, 0, 0, $day, $mon, $yr);# midnight today
while ($dow != $target_dow) {
  # Back up one day
  $start -= $seconds_per_day;   # hope no DST! :-)
  if (--$dow < 0) {
$dow += 7;
  }
}
my $stop = $start + $seconds_per_day;

my($gather, $yield)  = gather_mtime_between($start, $stop);
find($gather, @starting_directories);
my @files = $yield->();

for my $file (@files) {
  my $mtime = (stat $file)[9];  # mtime via slice
  my $when = localtime $mtime;
  print "$when: $file\n";
}

I have 3 questions:
1) The $start and $stop variables in my subroutine are the $start and
$stop variables in the script at large.  However, I had to label these
with 'my' because I was getting error messages.  Will this cause
trouble?

2) How do I get the array @starting_directories into my first
anonymous subroutine?  I need @starting_directories to be in the same
place as @file_list.

3) When I run the script I get these error messages:
syntax error at last_mod.pl line 16, near "$timestamp <="
syntax error at last_mod.pl line 20, near "}"
I can't figure out what is causing these error messages.  The various
braces, etc. seem to match up.


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/