There are too many to list. I'll try anyway.
1 array = [1, 2, 3]
2 x = 5
3 array.collect! { | elem | elem + x }
4 p array # => [6, 7, 8]
1 array.each { | elem | puts elem }
2 hash.each { | key, val | puts "#{key} => #{val}" }
3 file.each { | line | puts line }
4 array.each_with_index { | elem, i |
5 puts "array[#{i}] = #{elem}"
6 }
7 array.include?(42)
1 (0 .. 9).each { | i | sum += i }
2 ('a' .. 'z').each { | str | puts str }
3 (0 ... array.size).each { | i | puts array[i] }
1 ie = WIN32OLE.new('InternetExplorer.Application')
2 ie.visible = true
3 ie.gohome
Much of this section is stolen from the Ruby site (see References below).
1 // ================
2 // Java
3
4 import java.io.*;
5
6 try {
7 BufferedReader in =
8 new BufferedReader(new FileReader(fileName));
9 String line;
10 while ((line = in.readLine()) != null) {
11 // Use the line...
12 }
13 }
14 catch (FileNotFoundException fnfe) {
15 System.err.println(fnfe.toString());
16 }
17 catch (IOException ioe) {
18 System.err.println(ioe.toString());
19 }
20
21 # ================
22 # Ruby
23
24 begin
25 IO.foreach(fileName) { | line |
26 # Use the line...
27 }
28 rescue
29 $stderr.puts $!
30 end
1 10.times do
2 # ...
3 end
1 mutex.synchronize do
2 # .. critical process ..
3 end
Here we have four code examples. The first three are relatively simple ``textbook'' examples that perform the same task in Java, C++, Smalltalk, Perl, and Ruby. The last is a slightly more complex example in Ruby only.
The Smalltalk code below was written using Squeak, a free implementation of Smalltalk. Sorry, but there are no Python examples. I don't know that language well enough. ObPython: ``My hovercraft is full of eels.''
The first example defines the same class in five different languages. In each, we define the class, create an instance, and print the string representation of the instance.
The example class is a Song. It has has a constructor, two instance variables, accessor methods (``getters'' and ``setters''), and a method for representing instances as strings.
1 // ================
2 // Java
3
4 public class Song {
5
6 protected String name;
7 protected int lengthInSeconds;
8
9 Song(String name, int len) {
10 this.name = name;
11 lengthInSeconds = len;
12 }
13
14 public String getName() { return name; }
15 public void setName(String str) { name = str; }
16
17 public int getLengthInSeconds()
18 { return lengthInSeconds; }
19 public void setLengthInSeconds(int secs)
20 { lengthInSeconds = secs; }
21
22 public String toString() {
23 return name + " (" + lengthInSeconds + " seconds)"
24 }
25
26 // Create and print
27 public void main(String[] args) {
28 s = new Song("name", 60);
29 System.out.println(s);
30 }
31 }
32
33 // ================
34 // C++
35
36 // Song.h
37 #ifndef Song_h
38 #define Song_h
39
40 #include <iostream>
41 #include <string>
42
43 class Song {
44 public:
45 Song(const char * nameStr = 0, int len = 0)
46 : name(nameStr ? nameStr : ""),
47 lengthInSeconds(len) {}
48
49 // The default copy constructor, destructor, and
50 // operator= are all acceptable. I'm glad, 'cause
51 // it's a pain to have to write them.
52
53 const char * getName() const { return name.data(); }
54 void setName(const char *str) { name = str; }
55
56 int getLengthInSeconds() const
57 { return lengthInSeconds; }
58 void setLengthInSeconds(int len)
59 { lengthInSeconds = len; }
60
61 protected:
62 string name;
63 int lengthInSeconds;
64
65 friend ostream &
66 operator<<(ostream &out, const Song &s);
67 };
68
69 ostream & operator<<(ostream &out, const Song &s) {
70 return out << s.name << " ("
71 << s.lengthInSeconds << " seconds)";
72 }
73
74 #endif Song_h
75
76 // Song.cpp
77 #include "Song.h"
78
79 main()
80 {
81 Song s("name", 60);
82 cout << s << endl;
83 }
84
85 " ================"
86 " Smalltalk"
87
88 Object subclassNamed: #Song
89 instanceVariables: 'name lengthInSeconds'
90 classVariables: ''
91 "..."
92
93 name
94 ^ name
95
96 name: aString
97 name := aString
98
99 lengthInSeconds
100 ^ lengthInSeconds
101
102 lengthInSeconds: aNumber
103 lengthInSeconds := aNumber
104
105 printOn: aStream
106 aStream nextPutAll: name.
107 aStream nextPut: $(.
108 aStream nextPutAll: lengthInSeconds printString.
109 aStream nextPutAll: ') seconds'
110
111 "Create and print a song.
112 Copy this code into a workspace and execute it."
113 s := Song new name: 'name'; lengthInSeconds: 60.
114 Transcript show: s asString; cr.
115
116 # ================
117 # Perl
118
119 package Song;
120
121 sub new {
122 my($class, $name, $len) = @_;
123 my $self = {};
124 $self->{'name'} = $name;
125 $self->{'lengthInSeconds'} = $len;
126 bless $self, class;
127 return $self;
128 }
129
130 sub name {
131 my($self) = shift;
132 if (@_) { $self->{'name'} = shift }
133 return $self->{'name'};
134 }
135
136 sub lengthInSeconds {
137 my($self) = shift;
138 if (@_) { $self->{'lengthInSeconds'} = shift }
139 return $self->{'lengthInSeconds'};
140 }
141
142 sub toString {
143 my($self) = shift;
144 return $self->name() . "(" . $self->lengthInSeconds()
145 . ") seconds";
146 }
147
148 # Create and print
149 $s = Song->new('name', 60);
150 print $s->toString() . "\n";
151
152 # ================
153 # Ruby
154
155 class Song
156
157 # Not only declare instance variables (which is
158 # unnecessary) but also create accessor methods
159 # (getters and setters). "attr_reader" creates
160 # just getters and "attr_writer" creates just
161 # setters.
162 attr_accessor :name, :lengthInSeconds
163
164 # The constructor, sort of. This method is called
165 # by the class method "new".
166 def initialize(name, len)
167 @name = name
168 @lengthInSeconds = len
169 end
170
171 def to_s
172 return "#{name} (#{lengthInSeconds} seconds)"
173 end
174 end
175
176 # Create and print. Only run this code if this file
177 # is being executed directly, else ignore it.
178 if $0 == __FILE__
179 s = Song.new('name', 60)
180 puts s
181 end
In this example we will create a linear collection of Song instances, add a song, and iterate over the collection.
The Java version uses the J2EE collection classes. The C++ version uses the Standard Template Library (STL) for its vector and iterator classes.
1 // ================
2 // Java
3
4 import java.util.*;
5
6 ArrayList songs = new ArrayList();
7 songs.add(new Song("name", 60));
8
9 for (Iterator iter = songs.iterator(); iter.hasNext(); ) {
10 Song s = (Song)iter.next(); // Yuck!
11 // Do something with s...
12 }
13
14 // ================
15 // C++
16
17 #include <vector>
18 #include "Song.h"
19
20 main()
21 {
22 vector<Song> songs;
23 songs.push_back(Song("name", 60));
24
25 vector<Song>::iterator iter(songs.begin());
26 for (; iter != songs.end(); ++iter) {
27 Song s = *iter;
28 // Do something with s...
29 }
30 }
31
32 " ================"
33 " Smalltalk"
34
35 songs := OrderedCollection new.
36 songs add: (Song new name: 'name'; lengthInSeconds: 60).
37 songs do: [ :s |
38 "Do something with s..."
39 ].
40
41 # ================
42 # Perl
43
44 @songs = ();
45 push(@songs, Song->new("name", 60));
46 foreach $s (@songs) {
47 # Do something with $s...
48 }
49
50 # ================
51 # Ruby
52
53 songs = []
54 songs << Song.new("name", 60)
55 songs.each { | s |
56 # Do something with s...
57 }
In this example, we will manipulate a comma-delimited data file by opening it, reading each line, separating each line into columns, and printing the columns as a SQL INSERT statement.
For simplicity's sake, we will assume that the data does not contain any comma characters. This code does handle ``empty'' columns (two consecutive commas). Because of this, we often can't use the most obvious or clean solution (for example, a StringTokenizer in Java or strtok() in C++).
I have Ruby, Perl, and Smalltalk classes that handle Excel comma- and tab-delimited data--quotes and all--that are yours for the asking. A mini state machine is necessary to handle the quotes and delimiter chars properly.
1 // ================
2 // Java
3
4 import java.io.*;
5 import java.util.*;
6
7 public class DataFileReader {
8
9 public static void main(String[] args) {
10 DataFileReader dfr = new DataFileReader();
11 dfr.readFile(args[0]);
12 }
13
14 public void readFile(String fileName) {
15 try {
16 BufferedReader in =
17 new BufferedReader(new FileReader(fileName));
18 String line;
19 while ((line = in.readLine()) != null) {
20 Collection list = splitIntoColumns(line);
21 printAsInsertStatements(list);
22 }
23 }
24 catch (FileNotFoundException fnfe) {
25 System.err.println(fnfe.toString());
26 }
27 catch (IOException ioe) {
28 System.err.println(ioe.toString());
29 }
30 }
31
32 public Collection splitIntoColumns(String line) {
33 ArrayList array = new ArrayList();
34
35 // Using StringTokenizer here is almost useless. It
36 // either skips or returns multiple adjacent commas,
37 // but doesn't report the emptiness between as empty
38 // data columns.
39 int pos = line.indexOf(",");
40 while (pos != -1) {
41 array.add(line.substring(0, pos));
42 line = line.substring(pos + 1);
43 pos = line.indexOf(",");
44 }
45 if (line.length() > 0)
46 array.add(line);
47
48 return array;
49 }
50
51 public void printAsInsertStatements(Collection list) {
52 System.out.print("insert into table values (\n\t");
53 boolean first = true;
54
55 Iterator iter = list.iterator();
56 while (iter.hasNext()) {
57 String col = (String)iter.next();
58
59 if (first) first = false;
60 else System.out.print(",\n\t");
61
62 System.out.print("'" + col + "'");
63 }
64 System.out.println("\n)");
65 }
66
67 }
68
69 // ================
70 // C++
71
72 #include <string>
73 #include <iostream>
74 #include <fstream>
75 #include <vector>
76
77 static const int BUFSIZ = 1024;
78
79 vector<string> splitIntoColumns(char *line);
80 void printAsInsertStatements(vector<string> &list);
81
82 void
83 main(int argc, char *argv[])
84 {
85 ifstream in(argv[1]);
86 char line[BUFSIZ];
87 while (!in.eof()) {
88 in.getline(line, BUFSIZ);
89 if (strlen(line) == 0)
90 break;
91 vector<string> list = splitIntoColumns(line);
92 printAsInsertStatements(list);
93 }
94 }
95
96 vector<string>
97 splitIntoColumns(char *line)
98 {
99 vector<string> list;
100
101 // Using strtok() here is useless. It skips multiple
102 // adjacent commas and doesn't report the emptyness
103 // between as empty data columns.
104 char *nextComma = index(line, ',');
105 while (nextComma != 0) {
106 list.push_back(string(line, nextComma - line));
107 line = nextComma + 1;
108 nextComma = index(line, ',');
109 }
110 if (strlen(line) > 0)
111 list.push_back(string(line));
112
113 return list;
114 }
115
116 void
117 printAsInsertStatements(vector<string> &list)
118 {
119 cout << "insert into table values (" << endl << "\t";
120 bool first = true;
121
122 vector<string>::iterator iter(list.begin());
123 for ( ; iter != list.end(); ++iter) {
124 string col = *iter;
125
126 if (first) first = false;
127 else cout << "," << endl << "\t";
128
129 cout << "'" << col << "'";
130 }
131 cout << endl << ")" << endl;
132 }
133
134
135 " ================"
136 " Smalltalk"
137
138 Object subclass: #DataFileReader
139 instanceVariableNames: ''
140 classVariableNames: ''
141 poolDictionaries: ''
142 category: 'Jim-Utils'
143
144 readFile: fileName
145 | inStream outStream list |
146 inStream :=
147 CrLfFileStream readOnlyFileNamed: fileName.
148 outStream :=
149 FileStream newFileNamed: fileName, '.out'.
150 [inStream atEnd] whileFalse: [
151 list := self parseNextLine: inStream.
152 self output: list onStream: outStream.
153 ].
154
155 parseNextLine: aStream
156 "Read columns in line and shove them into a list.
157 Return the list."
158 | list line lineStream |
159 list := OrderedCollection new. "Create empty list."
160 line := aStream nextLine. "Read line from input file."
161
162 "Read columns in line and shove into list."
163 lineStream := ReadStream on: line
164 from: 1
165 to: line size.
166 [lineStream atEnd] whileFalse: [
167 list add: (lineStream upTo: $,).
168 ].
169 ^ list
170
171 output: list onStream: outStream
172 "Output insert statement."
173 outStream nextPutAll: 'insert into table values (
174 '''.
175 list do: [ :col |
176 outStream nextPutAll: col
177 ] separatedBy: [
178 outStream nextPutAll: ''',
179 '''.
180 ].
181 outStream nextPutAll: '''
182 )
183 '.
184
185 "Finally, create and use one of these suckers. Type
186 this in a workspace, select it, and choose 'do it'.
187 Actually, this code can be anywhere, including in
188 a comment. Just select it and execute it."
189 DataFileReader new readFile: 'foo.dat'.
190
191 # ================
192 # Perl
193
194 #! /usr/bin/perl
195
196 open(FILE, $ARGV[0]) ;
197 while (($line = <FILE>) ne '') {
198 chomp($line);
199 print "insert into table values (\n\t'";
200 print join("',\n\t'", split(/,/, $line));
201 print "',\n)\n";
202 }
203 close(FILE);
204
205 # ================
206 # Ruby
207
208 #! /usr/local/bin/ruby
209
210 # File is a subclass of IO. "foreach" is a class method
211 # that opens the file, executes the block of code once
212 # for each line, and closes the file.
213 IO.foreach(ARGV[0]) { | line |
214 line.chomp!()
215 puts "insert into table values ("
216 print "\t'"
217 print line.split(/,/).join("',\n\t'")
218 puts "'\n)"
219 }
This final example is Ruby-only. It shows a ``real'' script performing a slightly more complex task: parsing XML and capturing and printing any errors returned by the parser. The XML isn't processed by this script.
This is one of the example scripts that comes with NQXML.
1 #! /usr/bin/env ruby
2 #
3 # usage: parseTestStream.rb file_or_directory
4 #
5 # This script runs the streaming parser over the specified
6 # file or all .xml files within the specified directory.
7 #
8 # If an NQXML::ParserError is seen, an error message is
9 # printed and parsing stops.
10 #
11
12 # Start looking for NQXML classes in the directory above
13 # this one. This forces us to use the local copy of NQXML,
14 # even if there is a previously installed version out
15 # there somewhere. (Since this script comes as an example
16 # with NQXML, we want to make sure we are using the latest
17 # version that's right here, not one previously installed
18 # elsewhere.)
19 $LOAD_PATH[0, 0] = '..'
20
21 require 'nqxml/streamingparser'
22
23 def testParser(file)
24 print "Parsing file #{file}..."
25 $stdout.flush()
26 file = File.open(file, 'r')
27 parser = NQXML::StreamingParser.new(file)
28 begin
29 # Just let parser run through the XML
30 parser.each { | entity | }
31 rescue NQXML::ParserError => ex
32 puts "\n NQXML parser error, line #{ex.line}" +
33 " column #{ex.column}: #{$!}"
34 return
35 rescue
36 puts "\n Non-parser error: #{$!}"
37 return
38 ensure
39 # An "ensure" is like Java's "finally" clause:
40 # No matter what happens, this code gets executed.
41 # Instead of using an "ensure" we could have used
42 # a block as an argument to File.open. At the end
43 # of the block the file would have been closed
44 # automagically.
45 file.close() unless file.nil?
46 end
47 puts 'OK'
48 end
49
50 # Start of main code
51
52 # If we have a command-line argument, grab it and
53 # remove the trailing slash (if any). If no argument
54 # is specified, use '.' (the current directory).
55 DIR = ARGV[0] ? ARGV[0].gsub(/\/$/, '') : '.'
56
57 if File.directory?(DIR)
58 Dir.entries(DIR).each { | f |
59 testParser("#{DIR}/#{f}") if f =~ /\.xml$/
60 }
61 else
62 testParser(DIR)
63 end
This document was generated using the LaTeX2HTML translator Version 99.1 release (March 30, 1999)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -no_navigation -split 0 talk.tex
The translation was initiated by on 2001-07-13