From: mattmsykes@... (Matt M Sykes) Date: 2002-04-14T08:39:52+09:00 Subject: perl with a ruby accent So I learned some ruby today. Since I am coming from the perl world, I decided to write a simple script in both ruby and perl to see what I can learn. I was thinking the two scripts would be nearly identical; I would just be learning some syntax changes and such (OO paradigms aside for the moment). For example, the big thing in ruby is iterators, but those would just translate into perl closures or run-of-the-mill functions. Well the perl script didn't quite reflect the ruby script as much as I envisioned. But it wasn't because perl couldn't do something, it was because perl didn't do something. It is interesting that perl's find() function had the option of passing the filename to the 'wanted' function but chose not to do so, electing instead to communicate through global variables. I've used perl's find function many times over the years and never thought this was odd. There is definitely some measure of enlightenment that ruby thrusts upon the user. It is clear to me now that passing the argument to the function is cleaner and more "correct." At least find() could have passed the filename in addition to setting global variables. So, perl can iterate too, but perl users don't understand how. Or maybe the syntax creates a mindset or the mindset creates a syntax where iterating isn't considered. For instance, it never occurred to me that I could do sub open_and_iterate { my $filename = shift ; my $code = shift ; my $file ; open $file, $filename ; while(my $line = <$file>) { $code->($line) ; } close $file ; } open_and_iterate(shift, sub { my $line = shift ; print "got $line" ; }) ; I might even do this next time I happen to be writing perl. I'm sure it would raise the eyebrows of some coworkers :) #!/usr/local/bin/ruby # # Usage: clean [-r] [dir1, [dir2, ...]] # # Removes junk files from dir1, dir2, ... # # If no directory is given, the current directory is cleaned. # # -r for recursive cleaning. # require "find" junk = [ '~$', '\.core$', '^core$', '^#.*#$', '\.trace$', ] recursive = false if not ARGV.empty? and ARGV[0] == '-r' recursive = true ARGV.shift end ARGV.push('.') if ARGV.empty? ARGV.each { |arg| arg.sub!('/+$','') } clean = Proc.new do |file| next unless File.file?(file) junk.each do |re| if file =~ re puts file #unlink file break end end end ARGV.each do |dir| next unless File.directory?(dir) if recursive Find.find(dir,&clean) else Dir.foreach(dir) do |file| clean.call(dir + "/" + file) end end end #!/usr/bin/perl # # Usage: clean [-r] [dir1, [dir2, ...]] # # Removes junk files from dir1, dir2, ... # # If no directory is given, the current directory is cleaned. # # -r for recursive cleaning. # use strict ; use warnings ; use File::Find () ; my @junk = ( '~$', '\.core$', '^core$', '^#.*#$', '\.trace$', ) ; my $recursive = 0 ; if( @ARGV and $ARGV[0] eq '-r' ) { $recursive = 1 ; shift @ARGV ; } push @ARGV,'.' unless @ARGV ; for my $arg (@ARGV) { $arg =~ s!/+$!! ; } sub clean { my $file = shift ; return unless -f $file ; for my $re (@junk) { if( $file =~ $re ) { print "$file\n" ; #unlink $file ; last ; } } } sub cleanwrapper { clean($File::Find::name) ; } for my $dir (@ARGV) { next unless -d $dir ; if( $recursive ) { File::Find::find({wanted => \&cleanwrapper, no_chdir => 1},$dir) ; } else { my $dirh ; opendir $dirh, $dir ; for my $file (readdir $dirh) { clean("$dir/$file") ; } } }