六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 33|回复: 0

Perl vs. Python vs. Ruby

[复制链接]

升级  0.6%

159

主题

159

主题

159

主题

进士

Rank: 4

积分
503
 楼主| 发表于 2013-1-15 02:48:15 | 显示全部楼层 |阅读模式
I’m evaluating Python and Ruby as replacements for Perl.I’ve been using Perl for several years and am very comfortable with it,although I’m definitely not an expert. Perl is a powerful language, butI think it’s ugly and encourages writing bad code, so I want to get ridof it. Python and Ruby both come with Mac OS X 10.2, both have BBEdit language modules, and both promise a cleaner approach to scripting. Over the past few weeks I read the Python Tutorial and the non-reference parts of Programming Ruby, however as of this afternoon I’d not written any Python or Ruby code yet.
Here’s a toy problem I wanted to solve. eSellerate gives me a tab-delimited file containing information about the people who bought my shareware.I wanted a script to extract from this file the e-mail addresses ofpeople who asked to be contacted when I release the new versions of theproducts.
I decided to solve this problem in each language and then comparethe resulting programs. The algorithm I chose was just the first onethat came to mind. I coded it first in Ruby, and then ported the codeto Python and Perl, changing it as little as possible. Thus, the styleis perhaps not canonical Python or Perl, although since I’m new to Rubyit’s probably not canonical Ruby either. If I were just writing this in Perl, I might have tried to avoid Perl’s messy syntax for nested arrays and instead used an array of strings.
Here’s the basic algorithm:

  • Read each line of standard input and break it into fields at each tab.
  • Each field is wrapped in quotation marks, so remove them. Assume that there are no quotation marks in the interior of the field.
  • Store the fields in an array called record.
  • Create another array, records and fill it with all the records.
  • Make a new array, contactRecords, that contains arrays of just the fields we care about: SKUTITLE, CONTACTME, EMAIL.
  • Sort contactRecords by SKUTITLE.
  • Remove the elements of contactRecords where CONTACTME is not 1.
  • Print contactRecords to standard output, with the fields separated by tabs and the records separated by newlines.
And here’s the code:
Perl

#!/usr/bin/perl -wuse strict;my @records = ();foreach my $line ( <> ){    my @record = map {s/"//g; $_} split("\t", $line);    push(@records, \@record);}my $EMAIL = 17;my $CONTACTME = 27;my $SKUTITLE = 34;my @contactRecords = ();foreach my $r ( @records ){    push(@contactRecords, [$$r[$SKUTITLE], $$r[$CONTACTME], $$r[$EMAIL]]);}@contactRecords = sort {$$a[0] cmp $$b[0]} @contactRecords;@contactRecords = grep($$_[1] eq "1", @contactRecords);foreach my $r ( @contactRecords ){    print join("\t", @$r), "\n";}The punctuation and my’s make this harder to read than it should be.
Python

#!/usr/bin/pythonimport fileinputrecords = []for line in fileinput.input():    record = [field.replace('"', '') for field in line.split("\t")]    records.append(record)EMAIL = 17CONTACTME = 27SKUTITLE = 34contactRecords = [[r[SKUTITLE], r[CONTACTME], r[EMAIL]] for r in records]contactRecords.sort() # default sort will group by sku titlecontactRecords = filter(lambda r: r[1] == "1", contactRecords)for r in contactRecords:    print "\t".join(r)I think the Python version is generally the cleanest to read—that is, it’s the most English-like. I had to look up how join and filter worked, because they weren’t methods of list as I had guessed.
Ruby

#!/usr/bin/rubyrecords = []while gets    record = $_.split('\t').collect! {|field| field.gsub('"', '') }    records << recordendEMAIL = 17CONTACTME = 27SKUTITLE = 34contactRecords = records.collect {|r| [r[SKUTITLE], r[CONTACTME], r[EMAIL]] }contactRecords.sort! # default sort will group by sku titlecontactRecords.reject! {|a| a[1] != "1"}contactRecords.each {|r|    print r.join("\t"), "\n"}This is actually the shortest version, and I think it’s the easiestto read if you aren’t put off by the block syntax. I like how thesequence of operations in the first line of the whileisn’t “backwards” as it is in the Perl and Python versions. Also, Icorrectly guessed which classes “owned” the methods and whether theywere mutators.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表