diff options
author | murphy <murphy@rubychan.de> | 2005-10-29 04:55:53 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2005-10-29 04:55:53 +0000 |
commit | 32440c8970eb351320ed3a9d5a986d275d3371c8 (patch) | |
tree | e86c71a856593d14ba03ce896f6ac773cddb6fec | |
parent | fb64737038ca13b4047219c429560b97b98fe22b (diff) | |
download | coderay-32440c8970eb351320ed3a9d5a986d275d3371c8.tar.gz |
Added Test environment.
-rw-r--r-- | test/ALL-TESTS.rb | 5 | ||||
-rw-r--r-- | test/ruby/1.in.rb | 729 | ||||
-rw-r--r-- | test/ruby/1.out.raydebug | 729 | ||||
-rw-r--r-- | test/ruby/class.in.rb | 83 | ||||
-rw-r--r-- | test/ruby/class.out.raydebug | 83 | ||||
-rw-r--r-- | test/ruby/comment.in.rb | 17 | ||||
-rw-r--r-- | test/ruby/comment.out.raydebug | 17 | ||||
-rw-r--r-- | test/ruby/evil.in.rb | 1123 | ||||
-rw-r--r-- | test/ruby/evil.out.raydebug | 1123 | ||||
-rw-r--r-- | test/ruby/pleac.in.rb | 6368 | ||||
-rw-r--r-- | test/ruby/pleac.out.raydebug | 6368 | ||||
-rw-r--r-- | test/ruby/quotes.in.rb | 1 | ||||
-rw-r--r-- | test/ruby/quotes.out.raydebug | 1 | ||||
-rw-r--r-- | test/ruby/sidebarize.in.rb | 145 | ||||
-rw-r--r-- | test/ruby/sidebarize.out.raydebug | 145 | ||||
-rw-r--r-- | test/ruby/simple.in.rb | 2 | ||||
-rw-r--r-- | test/ruby/simple.out.raydebug | 2 | ||||
-rw-r--r-- | test/ruby/suite.rb | 9 | ||||
-rw-r--r-- | test/ruby/undef.in.rb | 18 | ||||
-rw-r--r-- | test/ruby/undef.out.raydebug | 18 | ||||
-rw-r--r-- | test/ruby/zero.in.rb | 0 | ||||
-rw-r--r-- | test/ruby/zero.out.raydebug | 0 | ||||
-rw-r--r-- | test/suite.rb | 106 |
23 files changed, 17092 insertions, 0 deletions
diff --git a/test/ALL-TESTS.rb b/test/ALL-TESTS.rb new file mode 100644 index 0000000..4014cdc --- /dev/null +++ b/test/ALL-TESTS.rb @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +$:.unshift "../lib" + +Dir.chdir File.dirname(__FILE__) +Dir["**/tc_*.rb"].each { |file| load file } diff --git a/test/ruby/1.in.rb b/test/ruby/1.in.rb new file mode 100644 index 0000000..b5baffd --- /dev/null +++ b/test/ruby/1.in.rb @@ -0,0 +1,729 @@ +class String
+ def / regex
+ scan(regex).first
+ end
+end
+
+module Bytes
+ KILOBYTE, MEGABYTE, GIGABYTE, TERABYTE, PETABYTE = (1..5).map { |x| 2 ** (10 * x) }
+ FactorOfSuffix = Hash.new(1)
+ constants.each do |c|
+ FactorOfSuffix[c[0,1]] = const_get c
+ end
+
+ def Bytes.factor_of_suffix suff
+ FactorOfSuffix[suff]
+ end
+
+ def Bytes.[] str
+ n, fac = str / /(.+)([A-Z])/
+ n = n.to_i
+ fac = factor_of_suffix fac
+ n * fac
+ end
+end
+
+class String
+ def to_bytes
+ Bytes[self]
+ end
+end
+
+p '01K'.to_bytes
+p '%d - %p' % [Bytes.constants.size, self]
+
+p 'abc' / /([ac])/
+
+p 'abc' + /([ac])/
+p 'abc' - /([ac])/
+p 'abc' * /([ac])/
+p 'abc' ** /([ac])/
+p 'abc' % /([ac])/
+p 'abc' ~ /([ac])/
+
+require 'benchmark'
+S = 'bla' * 100 + "\n" + "\t"*4
+T = 200000
+
+Benchmark.bm(1) do |bm|
+ GC.sweep
+ bm.report('?') { T.times { S.index(?\n) } }
+ GC.sweep
+ bm.report('"') { T.times { S.index("\n") } }
+ GC.sweep
+ bm.report('/') { T.times { S.index(/\n/) } }
+ GC.sweep
+end
+
+ def next?()
+ !end?
+ end
+ # Rewinds the generator.
+ def rewind()
+ initialize(nil, &@block) if @index.nonzero?
+
+ self
+ end
+
+a = []
+a << a
+p a #-> [[...]]
+
+# format.rb: Written by Tadayoshi Funaba 1999-2004
+# $Id: format.rb,v 2.14 2004-11-06 10:58:40+09 tadf Exp $
+
+require 'rational'
+
+class Date
+
+ MONTHS = {
+ 'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4,
+ 'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8,
+ 'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12
+ }
+
+ DAYS = {
+ 'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3,
+ 'thursday' => 4, 'friday' => 5, 'saturday' => 6
+ }
+
+ ABBR_MONTHS = {
+ 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
+ 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
+ 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12
+ }
+
+ ABBR_DAYS = {
+ 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
+ 'thu' => 4, 'fri' => 5, 'sat' => 6
+ }
+
+ ZONES = {
+ 'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600,
+ 'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
+ 'pst' => -8*3600, 'pdt' => -7*3600,
+ 'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600,
+ 'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600,
+ 'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600,
+ 'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600,
+ 'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600,
+ 'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600,
+ 'z' => 0*3600,
+ 'utc' => 0*3600, 'wet' => 0*3600, 'bst' => 1*3600, 'wat' => -1*3600,
+ 'at' => -2*3600, 'ast' => -4*3600, 'adt' => -3*3600, 'yst' => -9*3600,
+ 'ydt' => -8*3600, 'hst' =>-10*3600, 'hdt' => -9*3600, 'cat' =>-10*3600,
+ 'ahst'=>-10*3600, 'nt' =>-11*3600, 'idlw'=>-12*3600, 'cet' => 1*3600,
+ 'met' => 1*3600, 'mewt'=> 1*3600, 'mest'=> 2*3600, 'mesz'=> 2*3600,
+ 'swt' => 1*3600, 'sst' => 2*3600, 'fwt' => 1*3600, 'fst' => 2*3600,
+ 'eet' => 2*3600, 'bt' => 3*3600, 'zp4' => 4*3600, 'zp5' => 5*3600,
+ 'zp6' => 6*3600, 'wast'=> 7*3600, 'wadt'=> 8*3600, 'cct' => 8*3600,
+ 'jst' => 9*3600, 'east'=> 10*3600, 'eadt'=> 11*3600, 'gst' => 10*3600,
+ 'nzt' => 12*3600, 'nzst'=> 12*3600, 'nzdt'=> 13*3600, 'idle'=> 12*3600
+ }
+
+ def self.__strptime(str, fmt, elem)
+ fmt.scan(/%[EO]?.|./o) do |c|
+ cc = c.sub(/\A%[EO]?(.)\Z/o, '%\\1')
+ case cc
+ when /\A\s/o
+ str.sub!(/\A[\s\v]+/o, '')
+ when '%A', '%a'
+ return unless str.sub!(/\A([a-z]+)\b/io, '')
+ val = DAYS[$1.downcase] || ABBR_DAYS[$1.downcase]
+ return unless val
+ elem[:wday] = val
+ when '%B', '%b', '%h'
+ return unless str.sub!(/\A([a-z]+)\b/io, '')
+ val = MONTHS[$1.downcase] || ABBR_MONTHS[$1.downcase]
+ return unless val
+ elem[:mon] = val
+ when '%C'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ elem[:cent] = val
+ when '%c'
+ return unless __strptime(str, '%a %b %e %H:%M:%S %Y', elem)
+ when '%D'
+ return unless __strptime(str, '%m/%d/%y', elem)
+ when '%d', '%e'
+ return unless str.sub!(/\A ?(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..31) === val
+ elem[:mday] = val
+ when '%F'
+ return unless __strptime(str, '%Y-%m-%d', elem)
+ when '%G'
+ return unless str.sub!(/\A([-+]?\d+)/o, '')
+ val = $1.to_i
+ elem[:cwyear] = val
+ when '%g'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..99) === val
+ elem[:cwyear] = val
+ elem[:cent] ||= if val >= 69 then 19 else 20 end
+ when '%H', '%k'
+ return unless str.sub!(/\A ?(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..24) === val
+ elem[:hour] = val
+ when '%I', '%l'
+ return unless str.sub!(/\A ?(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..12) === val
+ elem[:hour] = val
+ when '%j'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..366) === val
+ elem[:yday] = val
+ when '%M'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..59) === val
+ elem[:min] = val
+ when '%m'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..12) === val
+ elem[:mon] = val
+ when '%n'
+ return unless __strptime(str, ' ', elem)
+ when '%p', '%P'
+ return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/io, '')
+ elem[:merid] = if $1.downcase == 'a' then 0 else 12 end
+ when '%R'
+ return unless __strptime(str, '%H:%M', elem)
+ when '%r'
+ return unless __strptime(str, '%I:%M:%S %p', elem)
+ when '%S'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..60) === val
+ elem[:sec] = val
+ when '%s'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ elem[:seconds] = val
+ when '%T'
+ return unless __strptime(str, '%H:%M:%S', elem)
+ when '%t'
+ return unless __strptime(str, ' ', elem)
+ when '%U', '%W'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..53) === val
+ elem[if c == '%U' then :wnum0 else :wnum1 end] = val
+ when '%u'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..7) === val
+ elem[:cwday] = val
+ when '%V'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (1..53) === val
+ elem[:cweek] = val
+ when '%v'
+ return unless __strptime(str, '%e-%b-%Y', elem)
+ when '%w'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..6) === val
+ elem[:wday] = val
+ when '%X'
+ return unless __strptime(str, '%H:%M:%S', elem)
+ when '%x'
+ return unless __strptime(str, '%m/%d/%y', elem)
+ when '%Y'
+ return unless str.sub!(/\A([-+]?\d+)/o, '')
+ val = $1.to_i
+ elem[:year] = val
+ when '%y'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ return unless (0..99) === val
+ elem[:year] = val
+ elem[:cent] ||= if val >= 69 then 19 else 20 end
+ when '%Z', '%z'
+ return unless str.sub!(/\A([-+:a-z0-9]+(?:\s+dst\b)?)/io, '')
+ val = $1
+ elem[:zone] = val
+ offset = zone_to_diff(val)
+ elem[:offset] = offset
+ when '%%'
+ return unless str.sub!(/\A%/o, '')
+ when '%+'
+ return unless __strptime(str, '%a %b %e %H:%M:%S %Z %Y', elem)
+=begin
+ when '%.'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i.to_r / (10**$1.size)
+ elem[:sec_fraction] = val
+=end
+ when '%1'
+ return unless str.sub!(/\A(\d+)/o, '')
+ val = $1.to_i
+ elem[:jd] = val
+ when '%2'
+ return unless __strptime(str, '%Y-%j', elem)
+ when '%3'
+ return unless __strptime(str, '%F', elem)
+ else
+ return unless str.sub!(Regexp.new('\\A' + Regexp.quote(c)), '')
+ end
+ end
+
+ if cent = elem.delete(:cent)
+ if elem[:cwyear]
+ elem[:cwyear] += cent * 100
+ end
+ if elem[:year]
+ elem[:year] += cent * 100
+ end
+ end
+
+ if merid = elem.delete(:merid)
+ if elem[:hour]
+ elem[:hour] %= 12
+ elem[:hour] += merid
+ end
+ end
+
+ str
+ end
+
+ private_class_method :__strptime
+
+ def self._strptime(str, fmt='%F')
+ elem = {}
+ elem if __strptime(str.dup, fmt, elem)
+ end
+
+ PARSE_MONTHPAT = ABBR_MONTHS.keys.join('|')
+ PARSE_DAYPAT = ABBR_DAYS. keys.join('|')
+
+ def self._parse(str, comp=false)
+ str = str.dup
+
+ str.gsub!(/[^-+,.\/:0-9a-z]+/ino, ' ')
+
+ # day
+ if str.sub!(/(#{PARSE_DAYPAT})\S*/ino, ' ')
+ wday = ABBR_DAYS[$1.downcase]
+ end
+
+ # time
+ if str.sub!(
+ /(\d+):(\d+)
+ (?:
+ :(\d+)(?:[,.](\d*))?
+ )?
+ (?:
+ \s*
+ ([ap])(?:m\b|\.m\.)
+ )?
+ (?:
+ \s*
+ (
+ [a-z]+(?:\s+dst)?\b
+ |
+ [-+]\d+(?::?\d+)
+ )
+ )?
+ /inox,
+ ' ')
+ hour = $1.to_i
+ min = $2.to_i
+ sec = $3.to_i if $3
+ if $4
+ sec_fraction = $4.to_i.to_r / (10**$4.size)
+ end
+
+ if $5
+ hour %= 12
+ if $5.downcase == 'p'
+ hour += 12
+ end
+ end
+
+ if $6
+ zone = $6
+ end
+ end
+
+ # eu
+ if str.sub!(
+ /(\d+)\S*
+ \s+
+ (#{PARSE_MONTHPAT})\S*
+ (?:
+ \s+
+ (-?\d+)
+ )?
+ /inox,
+ ' ')
+ mday = $1.to_i
+ mon = ABBR_MONTHS[$2.downcase]
+
+ if $3
+ year = $3.to_i
+ if $3.size > 2
+ comp = false
+ end
+ end
+
+ # us
+ elsif str.sub!(
+ /(#{PARSE_MONTHPAT})\S*
+ \s+
+ (\d+)\S*
+ (?:
+ \s+
+ (-?\d+)
+ )?
+ /inox,
+ ' ')
+ mon = ABBR_MONTHS[$1.downcase]
+ mday = $2.to_i
+
+ if $3
+ year = $3.to_i
+ if $3.size > 2
+ comp = false
+ end
+ end
+
+ # iso
+ elsif str.sub!(/([-+]?\d+)-(\d+)-(-?\d+)/no, ' ')
+ year = $1.to_i
+ mon = $2.to_i
+ mday = $3.to_i
+
+ if $1.size > 2
+ comp = false
+ elsif $3.size > 2
+ comp = false
+ mday, mon, year = year, mon, mday
+ end
+
+ # jis
+ elsif str.sub!(/([MTSH])(\d+)\.(\d+)\.(\d+)/ino, ' ')
+ e = { 'm'=>1867,
+ 't'=>1911,
+ 's'=>1925,
+ 'h'=>1988
+ }[$1.downcase]
+ year = $2.to_i + e
+ mon = $3.to_i
+ mday = $4.to_i
+
+ # vms
+ elsif str.sub!(/(-?\d+)-(#{PARSE_MONTHPAT})[^-]*-(-?\d+)/ino, ' ')
+ mday = $1.to_i
+ mon = ABBR_MONTHS[$2.downcase]
+ year = $3.to_i
+
+ if $1.size > 2
+ comp = false
+ year, mon, mday = mday, mon, year
+ elsif $3.size > 2
+ comp = false
+ end
+
+ # sla
+ elsif str.sub!(%r|(-?\d+)/(\d+)(?:/(-?\d+))?|no, ' ')
+ mon = $1.to_i
+ mday = $2.to_i
+
+ if $3
+ year = $3.to_i
+ if $3.size > 2
+ comp = false
+ end
+ end
+
+ if $3 && $1.size > 2
+ comp = false
+ year, mon, mday = mon, mday, year
+ end
+
+ # ddd
+ elsif str.sub!(
+ /([-+]?)(\d{4,14})
+ (?:
+ \s*
+ T?
+ \s*
+ (\d{2,6})(?:[,.](\d*))?
+ )?
+ (?:
+ \s*
+ (
+ Z
+ |
+ [-+]\d{2,4}
+ )
+ \b
+ )?
+ /inox,
+ ' ')
+ case $2.size
+ when 4
+ mon = $2[ 0, 2].to_i
+ mday = $2[ 2, 2].to_i
+ when 6
+ year = ($1 + $2[ 0, 2]).to_i
+ mon = $2[ 2, 2].to_i
+ mday = $2[ 4, 2].to_i
+ when 8, 10, 12, 14
+ year = ($1 + $2[ 0, 4]).to_i
+ mon = $2[ 4, 2].to_i
+ mday = $2[ 6, 2].to_i
+ hour = $2[ 8, 2].to_i if $2.size >= 10
+ min = $2[10, 2].to_i if $2.size >= 12
+ sec = $2[12, 2].to_i if $2.size >= 14
+ comp = false
+ end
+ if $3
+ case $3.size
+ when 2, 4, 6
+ hour = $3[ 0, 2].to_i
+ min = $3[ 2, 2].to_i if $3.size >= 4
+ sec = $3[ 4, 2].to_i if $3.size >= 6
+ end
+ end
+ if $4
+ sec_fraction = $4.to_i.to_r / (10**$4.size)
+ end
+ if $5
+ zone = $5
+ end
+ end
+
+ if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/ino, ' ')
+ if year
+ year = -year + 1
+ end
+ end
+
+ if comp and year
+ if year >= 0 and year <= 99
+ if year >= 69
+ year += 1900
+ else
+ year += 2000
+ end
+ end
+ end
+
+ elem = {}
+ elem[:year] = year if year
+ elem[:mon] = mon if mon
+ elem[:mday] = mday if mday
+ elem[:hour] = hour if hour
+ elem[:min] = min if min
+ elem[:sec] = sec if sec
+ elem[:sec_fraction] = sec_fraction if sec_fraction
+ elem[:zone] = zone if zone
+ offset = zone_to_diff(zone) if zone
+ elem[:offset] = offset if offset
+ elem[:wday] = wday if wday
+ elem
+ end
+
+ def self.zone_to_diff(str)
+ abb, dst = str.downcase.split(/\s+/o, 2)
+ if ZONES.include?(abb)
+ offset = ZONES[abb]
+ offset += 3600 if dst
+ elsif /\A([-+])(\d{2}):?(\d{2})?\Z/no =~ str
+ offset = $2.to_i * 3600 + $3.to_i * 60
+ offset *= -1 if $1 == '-'
+ end
+ offset
+ end
+
+ def strftime(fmt='%F')
+ o = ''
+ fmt.scan(/%[EO]?.|./o) do |c|
+ cc = c.sub(/^%[EO]?(.)$/o, '%\\1')
+ case cc
+ when '%A'; o << DAYNAMES[wday]
+ when '%a'; o << ABBR_DAYNAMES[wday]
+ when '%B'; o << MONTHNAMES[mon]
+ when '%b'; o << ABBR_MONTHNAMES[mon]
+ when '%C'; o << '%02d' % (year / 100.0).floor # P2,ID
+ when '%c'; o << strftime('%a %b %e %H:%M:%S %Y')
+ when '%D'; o << strftime('%m/%d/%y') # P2,ID
+ when '%d'; o << '%02d' % mday
+ when '%e'; o << '%2d' % mday
+ when '%F'; o << strftime('%Y-%m-%d') # ID
+ when '%G'; o << '%.4d' % cwyear # ID
+ when '%g'; o << '%02d' % (cwyear % 100) # ID
+ when '%H'; o << '%02d' % hour
+ when '%h'; o << strftime('%b') # P2,ID
+ when '%I'; o << '%02d' % ((hour % 12).nonzero? or 12)
+ when '%j'; o << '%03d' % yday
+ when '%k'; o << '%2d' % hour # AR,TZ,GL
+ when '%l'; o << '%2d' % ((hour % 12).nonzero? or 12) # AR,TZ,GL
+ when '%M'; o << '%02d' % min
+ when '%m'; o << '%02d' % mon
+ when '%n'; o << "\n" # P2,ID
+ when '%P'; o << if hour < 12 then 'am' else 'pm' end # GL
+ when '%p'; o << if hour < 12 then 'AM' else 'PM' end
+ when '%R'; o << strftime('%H:%M') # ID
+ when '%r'; o << strftime('%I:%M:%S %p') # P2,ID
+ when '%S'; o << '%02d' % sec
+ when '%s' # TZ,GL
+ d = ajd - self.class.jd_to_ajd(self.class.civil_to_jd(1970,1,1), 0)
+ s = (d * 86400).to_i
+ o << '%d' % s
+ when '%T'; o << strftime('%H:%M:%S') # P2,ID
+ when '%t'; o << "\t" # P2,ID
+ when '%U', '%W'
+ a = self.class.civil_to_jd(year, 1, 1, ns?) + 6
+ k = if c == '%U' then 0 else 1 end
+ w = (jd - (a - ((a - k) + 1) % 7) + 7) / 7
+ o << '%02d' % w
+ when '%u'; o << '%d' % cwday # P2,ID
+ when '%V'; o << '%02d' % cweek # P2,ID
+ when '%v'; o << strftime('%e-%b-%Y') # AR,TZ
+ when '%w'; o << '%d' % wday
+ when '%X'; o << strftime('%H:%M:%S')
+ when '%x'; o << strftime('%m/%d/%y')
+ when '%Y'; o << '%.4d' % year
+ when '%y'; o << '%02d' % (year % 100)
+ when '%Z'; o << (if offset.zero? then 'Z' else strftime('%z') end)
+ when '%z' # ID
+ o << if offset < 0 then '-' else '+' end
+ of = offset.abs
+ hh, fr = of.divmod(1.to_r/24)
+ mm = fr / (1.to_r/1440)
+ o << '%02d' % hh
+ o << '%02d' % mm
+ when '%%'; o << '%'
+ when '%+'; o << strftime('%a %b %e %H:%M:%S %Z %Y') # TZ
+=begin
+ when '%.'
+ o << '%06d' % (sec_fraction / (1.to_r/86400/(10**6)))
+=end
+ when '%1'; o << '%d' % jd
+ when '%2'; o << strftime('%Y-%j')
+ when '%3'; o << strftime('%Y-%m-%d')
+ else; o << c
+ end
+ end
+ o
+ end
+
+# alias_method :format, :strftime
+
+ def asctime() strftime('%c') end
+
+ alias_method :ctime, :asctime
+
+end
+
+class DateTime < Date
+
+ def self._strptime(str, fmt='%FT%T%Z')
+ super(str, fmt)
+ end
+
+ def strftime(fmt='%FT%T%Z')
+ super(fmt)
+ end
+
+end
+
+require 'generator'
+a = [2, 3, 5, 7, 11]
+b = %w#h a l l o#
+SyncEnumerator.new(a, b).each { |i, j|
+ puts "#{i} & #{j}"
+}
+
+class Signature < Array
+ def === x
+ x.kind_of? Array and zip(x).all? { |me, it| me === it }
+ end
+end
+
+module Chess
+
+ BOARD_RANGE = 1..8
+
+ class Position
+
+ attr_reader :x, :y
+
+ def initialize *args
+ @x, @y = case args
+ when Signature[Fixnum, Fixnum]
+ args
+ when Signature[String]
+ Position.decode args.first
+ else
+ raise ArgumentError, 'wrong number of arguments(one String or two fixnums)'
+ end
+ raise RuntimeError, '%p is out of the chess board' % self unless Position.valid? @x, @y
+ end
+
+ def inspect
+ 'Position(%p, %p)' % [x, y]
+ end
+
+ def Position.decode pos
+ x, y = pos.split('')
+ return x.upcase[0] - ?A + 1, @y = y[0] - ?0
+ end
+
+ def Position.valid? x, y
+ BOARD_RANGE.include? x and BOARD_RANGE.include? y
+ end
+ end
+
+end
+
+p Chess::Position.new('H3')
+SuperString = Class.new String
+p Chess::Position.new(SuperString.new('C5'))
+p Chess::Position.new(3, 6)
+p Chess::Position.new(3, 9)
+
+require 'grammar'
+
+def test_grammars
+ [<<EOG1, <<EOG2, <<EOG3,].map { |g| Grammar.new g }
+Z --> S
+S --> Sb
+S --> bAa
+A --> aSc
+A --> a
+A --> aSb
+EOG1
+
+C --> d
+C --> ABC
+B -->
+B --> c
+A --> B
+A --> a
+EOG2
+
+E - TD
+D - pTD
+D -
+T - FS
+S - uFS
+S -
+F - aEz
+F - i
+EOG3
+end
+
+$trace = false
+test_grammars.each_with_index do |g, i|
+ puts "Grammar #{i} is #{'not ' if g.ll1?}LL(1)."
+end
diff --git a/test/ruby/1.out.raydebug b/test/ruby/1.out.raydebug new file mode 100644 index 0000000..6575ccd --- /dev/null +++ b/test/ruby/1.out.raydebug @@ -0,0 +1,729 @@ +reserved(class) class(String)
+ reserved(def) method(/) ident(regex)
+ ident(scan)operator(()ident(regex)operator(\))operator(.)ident(first)
+ reserved(end)
+reserved(end)
+
+reserved(module) class(Bytes)
+ constant(KILOBYTE)operator(,) constant(MEGABYTE)operator(,) constant(GIGABYTE)operator(,) constant(TERABYTE)operator(,) constant(PETABYTE) operator(=) operator(()integer(1)operator(..)integer(5)operator(\))operator(.)ident(map) operator({) operator(|)ident(x)operator(|) integer(2) operator(**) operator(()integer(10) operator(*) ident(x)operator(\)) operator(})
+ constant(FactorOfSuffix) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(1)operator(\))
+ ident(constants)operator(.)ident(each) reserved(do) operator(|)ident(c)operator(|)
+ constant(FactorOfSuffix)operator([)ident(c)operator([)integer(0)operator(,)integer(1)operator(])operator(]) operator(=) ident(const_get) ident(c)
+ reserved(end)
+
+ reserved(def) constant(Bytes)operator(.)ident(factor_of_suffix) ident(suff)
+ constant(FactorOfSuffix)operator([)ident(suff)operator(])
+ reserved(end)
+
+ reserved(def) constant(Bytes)operator(.)operator([]) ident(str)
+ ident(n)operator(,) ident(fac) operator(=) ident(str) operator(/) regexp<delimiter(/)content((.+\)([A-Z]\))delimiter(/)>
+ ident(n) operator(=) ident(n)operator(.)ident(to_i)
+ ident(fac) operator(=) ident(factor_of_suffix) ident(fac)
+ ident(n) operator(*) ident(fac)
+ reserved(end)
+reserved(end)
+
+reserved(class) class(String)
+ reserved(def) method(to_bytes)
+ constant(Bytes)operator([)pre_constant(self)operator(])
+ reserved(end)
+reserved(end)
+
+ident(p) string<delimiter(')content(01K)delimiter(')>operator(.)ident(to_bytes)
+ident(p) string<delimiter(')content(%d - %p)delimiter(')> operator(%) operator([)constant(Bytes)operator(.)ident(constants)operator(.)ident(size)operator(,) pre_constant(self)operator(])
+
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(/) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(+) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(-) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(*) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(**) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(%) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+ident(p) string<delimiter(')content(abc)delimiter(')> operator(~) regexp<delimiter(/)content(([ac]\))delimiter(/)>
+
+ident(require) string<delimiter(')content(benchmark)delimiter(')>
+constant(S) operator(=) string<delimiter(')content(bla)delimiter(')> operator(*) integer(100) operator(+) string<delimiter(")char(\\n)delimiter(")> operator(+) string<delimiter(")char(\\t)delimiter(")>operator(*)integer(4)
+constant(T) operator(=) integer(200000)
+
+constant(Benchmark)operator(.)ident(bm)operator(()integer(1)operator(\)) reserved(do) operator(|)ident(bm)operator(|)
+ constant(GC)operator(.)ident(sweep)
+ ident(bm)operator(.)ident(report)operator(()string<delimiter(')content(?)delimiter(')>operator(\)) operator({) constant(T)operator(.)ident(times) operator({) constant(S)operator(.)ident(index)operator(()integer(?\\n)operator(\)) operator(}) operator(})
+ constant(GC)operator(.)ident(sweep)
+ ident(bm)operator(.)ident(report)operator(()string<delimiter(')content(")delimiter(')>operator(\)) operator({) constant(T)operator(.)ident(times) operator({) constant(S)operator(.)ident(index)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\)) operator(}) operator(})
+ constant(GC)operator(.)ident(sweep)
+ ident(bm)operator(.)ident(report)operator(()string<delimiter(')content(/)delimiter(')>operator(\)) operator({) constant(T)operator(.)ident(times) operator({) constant(S)operator(.)ident(index)operator(()regexp<delimiter(/)char(\\n)delimiter(/)>operator(\)) operator(}) operator(})
+ constant(GC)operator(.)ident(sweep)
+reserved(end)
+
+ reserved(def) method(next?)operator(()operator(\))
+ operator(!)ident(end?)
+ reserved(end)
+ comment(# Rewinds the generator.)
+ reserved(def) method(rewind)operator(()operator(\))
+ ident(initialize)operator(()pre_constant(nil)operator(,) operator(&)instance_variable(@block)operator(\)) reserved(if) instance_variable(@index)operator(.)ident(nonzero?)
+
+ pre_constant(self)
+ reserved(end)
+
+ident(a) operator(=) operator([)operator(])
+ident(a) operator(<<) ident(a)
+ident(p) ident(a) comment(#-> [[...]])
+
+comment(# format.rb: Written by Tadayoshi Funaba 1999-2004)
+comment(# $Id: format.rb,v 2.14 2004-11-06 10:58:40+09 tadf Exp $)
+
+ident(require) string<delimiter(')content(rational)delimiter(')>
+
+reserved(class) class(Date)
+
+ constant(MONTHS) operator(=) operator({)
+ string<delimiter(')content(january)delimiter(')> operator(=)operator(>) integer(1)operator(,) string<delimiter(')content(february)delimiter(')> operator(=)operator(>) integer(2)operator(,) string<delimiter(')content(march)delimiter(')> operator(=)operator(>) integer(3)operator(,) string<delimiter(')content(april)delimiter(')> operator(=)operator(>) integer(4)operator(,)
+ string<delimiter(')content(may)delimiter(')> operator(=)operator(>) integer(5)operator(,) string<delimiter(')content(june)delimiter(')> operator(=)operator(>) integer(6)operator(,) string<delimiter(')content(july)delimiter(')> operator(=)operator(>) integer(7)operator(,) string<delimiter(')content(august)delimiter(')> operator(=)operator(>) integer(8)operator(,)
+ string<delimiter(')content(september)delimiter(')>operator(=)operator(>) integer(9)operator(,) string<delimiter(')content(october)delimiter(')> operator(=)operator(>)integer(10)operator(,) string<delimiter(')content(november)delimiter(')> operator(=)operator(>)integer(11)operator(,) string<delimiter(')content(december)delimiter(')> operator(=)operator(>)integer(12)
+ operator(})
+
+ constant(DAYS) operator(=) operator({)
+ string<delimiter(')content(sunday)delimiter(')> operator(=)operator(>) integer(0)operator(,) string<delimiter(')content(monday)delimiter(')> operator(=)operator(>) integer(1)operator(,) string<delimiter(')content(tuesday)delimiter(')> operator(=)operator(>) integer(2)operator(,) string<delimiter(')content(wednesday)delimiter(')>operator(=)operator(>) integer(3)operator(,)
+ string<delimiter(')content(thursday)delimiter(')> operator(=)operator(>) integer(4)operator(,) string<delimiter(')content(friday)delimiter(')> operator(=)operator(>) integer(5)operator(,) string<delimiter(')content(saturday)delimiter(')> operator(=)operator(>) integer(6)
+ operator(})
+
+ constant(ABBR_MONTHS) operator(=) operator({)
+ string<delimiter(')content(jan)delimiter(')> operator(=)operator(>) integer(1)operator(,) string<delimiter(')content(feb)delimiter(')> operator(=)operator(>) integer(2)operator(,) string<delimiter(')content(mar)delimiter(')> operator(=)operator(>) integer(3)operator(,) string<delimiter(')content(apr)delimiter(')> operator(=)operator(>) integer(4)operator(,)
+ string<delimiter(')content(may)delimiter(')> operator(=)operator(>) integer(5)operator(,) string<delimiter(')content(jun)delimiter(')> operator(=)operator(>) integer(6)operator(,) string<delimiter(')content(jul)delimiter(')> operator(=)operator(>) integer(7)operator(,) string<delimiter(')content(aug)delimiter(')> operator(=)operator(>) integer(8)operator(,)
+ string<delimiter(')content(sep)delimiter(')> operator(=)operator(>) integer(9)operator(,) string<delimiter(')content(oct)delimiter(')> operator(=)operator(>)integer(10)operator(,) string<delimiter(')content(nov)delimiter(')> operator(=)operator(>)integer(11)operator(,) string<delimiter(')content(dec)delimiter(')> operator(=)operator(>)integer(12)
+ operator(})
+
+ constant(ABBR_DAYS) operator(=) operator({)
+ string<delimiter(')content(sun)delimiter(')> operator(=)operator(>) integer(0)operator(,) string<delimiter(')content(mon)delimiter(')> operator(=)operator(>) integer(1)operator(,) string<delimiter(')content(tue)delimiter(')> operator(=)operator(>) integer(2)operator(,) string<delimiter(')content(wed)delimiter(')> operator(=)operator(>) integer(3)operator(,)
+ string<delimiter(')content(thu)delimiter(')> operator(=)operator(>) integer(4)operator(,) string<delimiter(')content(fri)delimiter(')> operator(=)operator(>) integer(5)operator(,) string<delimiter(')content(sat)delimiter(')> operator(=)operator(>) integer(6)
+ operator(})
+
+ constant(ZONES) operator(=) operator({)
+ string<delimiter(')content(ut)delimiter(')> operator(=)operator(>) integer(0)operator(*)integer(3600)operator(,) string<delimiter(')content(gmt)delimiter(')> operator(=)operator(>) integer(0)operator(*)integer(3600)operator(,) string<delimiter(')content(est)delimiter(')> operator(=)operator(>) operator(-)integer(5)operator(*)integer(3600)operator(,) string<delimiter(')content(edt)delimiter(')> operator(=)operator(>) operator(-)integer(4)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(cst)delimiter(')> operator(=)operator(>) operator(-)integer(6)operator(*)integer(3600)operator(,) string<delimiter(')content(cdt)delimiter(')> operator(=)operator(>) operator(-)integer(5)operator(*)integer(3600)operator(,) string<delimiter(')content(mst)delimiter(')> operator(=)operator(>) operator(-)integer(7)operator(*)integer(3600)operator(,) string<delimiter(')content(mdt)delimiter(')> operator(=)operator(>) operator(-)integer(6)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(pst)delimiter(')> operator(=)operator(>) operator(-)integer(8)operator(*)integer(3600)operator(,) string<delimiter(')content(pdt)delimiter(')> operator(=)operator(>) operator(-)integer(7)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(a)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(b)delimiter(')> operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(c)delimiter(')> operator(=)operator(>) integer(3)operator(*)integer(3600)operator(,) string<delimiter(')content(d)delimiter(')> operator(=)operator(>) integer(4)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(e)delimiter(')> operator(=)operator(>) integer(5)operator(*)integer(3600)operator(,) string<delimiter(')content(f)delimiter(')> operator(=)operator(>) integer(6)operator(*)integer(3600)operator(,) string<delimiter(')content(g)delimiter(')> operator(=)operator(>) integer(7)operator(*)integer(3600)operator(,) string<delimiter(')content(h)delimiter(')> operator(=)operator(>) integer(8)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(i)delimiter(')> operator(=)operator(>) integer(9)operator(*)integer(3600)operator(,) string<delimiter(')content(k)delimiter(')> operator(=)operator(>) integer(10)operator(*)integer(3600)operator(,) string<delimiter(')content(l)delimiter(')> operator(=)operator(>) integer(11)operator(*)integer(3600)operator(,) string<delimiter(')content(m)delimiter(')> operator(=)operator(>) integer(12)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(n)delimiter(')> operator(=)operator(>) operator(-)integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(o)delimiter(')> operator(=)operator(>) operator(-)integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(p)delimiter(')> operator(=)operator(>) operator(-)integer(3)operator(*)integer(3600)operator(,) string<delimiter(')content(q)delimiter(')> operator(=)operator(>) operator(-)integer(4)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(r)delimiter(')> operator(=)operator(>) operator(-)integer(5)operator(*)integer(3600)operator(,) string<delimiter(')content(s)delimiter(')> operator(=)operator(>) operator(-)integer(6)operator(*)integer(3600)operator(,) string<delimiter(')content(t)delimiter(')> operator(=)operator(>) operator(-)integer(7)operator(*)integer(3600)operator(,) string<delimiter(')content(u)delimiter(')> operator(=)operator(>) operator(-)integer(8)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(v)delimiter(')> operator(=)operator(>) operator(-)integer(9)operator(*)integer(3600)operator(,) string<delimiter(')content(w)delimiter(')> operator(=)operator(>)operator(-)integer(10)operator(*)integer(3600)operator(,) string<delimiter(')content(x)delimiter(')> operator(=)operator(>)operator(-)integer(11)operator(*)integer(3600)operator(,) string<delimiter(')content(y)delimiter(')> operator(=)operator(>)operator(-)integer(12)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(z)delimiter(')> operator(=)operator(>) integer(0)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(utc)delimiter(')> operator(=)operator(>) integer(0)operator(*)integer(3600)operator(,) string<delimiter(')content(wet)delimiter(')> operator(=)operator(>) integer(0)operator(*)integer(3600)operator(,) string<delimiter(')content(bst)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(wat)delimiter(')> operator(=)operator(>) operator(-)integer(1)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(at)delimiter(')> operator(=)operator(>) operator(-)integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(ast)delimiter(')> operator(=)operator(>) operator(-)integer(4)operator(*)integer(3600)operator(,) string<delimiter(')content(adt)delimiter(')> operator(=)operator(>) operator(-)integer(3)operator(*)integer(3600)operator(,) string<delimiter(')content(yst)delimiter(')> operator(=)operator(>) operator(-)integer(9)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(ydt)delimiter(')> operator(=)operator(>) operator(-)integer(8)operator(*)integer(3600)operator(,) string<delimiter(')content(hst)delimiter(')> operator(=)operator(>)operator(-)integer(10)operator(*)integer(3600)operator(,) string<delimiter(')content(hdt)delimiter(')> operator(=)operator(>) operator(-)integer(9)operator(*)integer(3600)operator(,) string<delimiter(')content(cat)delimiter(')> operator(=)operator(>)operator(-)integer(10)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(ahst)delimiter(')>operator(=)operator(>)operator(-)integer(10)operator(*)integer(3600)operator(,) string<delimiter(')content(nt)delimiter(')> operator(=)operator(>)operator(-)integer(11)operator(*)integer(3600)operator(,) string<delimiter(')content(idlw)delimiter(')>operator(=)operator(>)operator(-)integer(12)operator(*)integer(3600)operator(,) string<delimiter(')content(cet)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(met)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(mewt)delimiter(')>operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(mest)delimiter(')>operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(mesz)delimiter(')>operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(swt)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(sst)delimiter(')> operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(fwt)delimiter(')> operator(=)operator(>) integer(1)operator(*)integer(3600)operator(,) string<delimiter(')content(fst)delimiter(')> operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(eet)delimiter(')> operator(=)operator(>) integer(2)operator(*)integer(3600)operator(,) string<delimiter(')content(bt)delimiter(')> operator(=)operator(>) integer(3)operator(*)integer(3600)operator(,) string<delimiter(')content(zp4)delimiter(')> operator(=)operator(>) integer(4)operator(*)integer(3600)operator(,) string<delimiter(')content(zp5)delimiter(')> operator(=)operator(>) integer(5)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(zp6)delimiter(')> operator(=)operator(>) integer(6)operator(*)integer(3600)operator(,) string<delimiter(')content(wast)delimiter(')>operator(=)operator(>) integer(7)operator(*)integer(3600)operator(,) string<delimiter(')content(wadt)delimiter(')>operator(=)operator(>) integer(8)operator(*)integer(3600)operator(,) string<delimiter(')content(cct)delimiter(')> operator(=)operator(>) integer(8)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(jst)delimiter(')> operator(=)operator(>) integer(9)operator(*)integer(3600)operator(,) string<delimiter(')content(east)delimiter(')>operator(=)operator(>) integer(10)operator(*)integer(3600)operator(,) string<delimiter(')content(eadt)delimiter(')>operator(=)operator(>) integer(11)operator(*)integer(3600)operator(,) string<delimiter(')content(gst)delimiter(')> operator(=)operator(>) integer(10)operator(*)integer(3600)operator(,)
+ string<delimiter(')content(nzt)delimiter(')> operator(=)operator(>) integer(12)operator(*)integer(3600)operator(,) string<delimiter(')content(nzst)delimiter(')>operator(=)operator(>) integer(12)operator(*)integer(3600)operator(,) string<delimiter(')content(nzdt)delimiter(')>operator(=)operator(>) integer(13)operator(*)integer(3600)operator(,) string<delimiter(')content(idle)delimiter(')>operator(=)operator(>) integer(12)operator(*)integer(3600)
+ operator(})
+
+ reserved(def) pre_constant(self)operator(.)ident(__strptime)operator(()ident(str)operator(,) ident(fmt)operator(,) ident(elem)operator(\))
+ ident(fmt)operator(.)ident(scan)operator(()regexp<delimiter(/)content(%[EO]?.|.)delimiter(/)modifier(o)>operator(\)) reserved(do) operator(|)ident(c)operator(|)
+ ident(cc) operator(=) ident(c)operator(.)ident(sub)operator(()regexp<delimiter(/)char(\\A)content(%[EO]?(.\))char(\\Z)delimiter(/)modifier(o)>operator(,) string<delimiter(')content(%)char(\\\\)content(1)delimiter(')>operator(\))
+ reserved(case) ident(cc)
+ reserved(when) regexp<delimiter(/)char(\\A)char(\\s)delimiter(/)modifier(o)>
+ ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content([)char(\\s)char(\\v)content(]+)delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%A)delimiter(')>operator(,) string<delimiter(')content(%a)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([a-z]+\))char(\\b)delimiter(/)modifier(io)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) constant(DAYS)operator([)global_variable($1)operator(.)ident(downcase)operator(]) operator(||) constant(ABBR_DAYS)operator([)global_variable($1)operator(.)ident(downcase)operator(])
+ reserved(return) reserved(unless) ident(val)
+ ident(elem)operator([)symbol(:wday)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%B)delimiter(')>operator(,) string<delimiter(')content(%b)delimiter(')>operator(,) string<delimiter(')content(%h)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([a-z]+\))char(\\b)delimiter(/)modifier(io)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) constant(MONTHS)operator([)global_variable($1)operator(.)ident(downcase)operator(]) operator(||) constant(ABBR_MONTHS)operator([)global_variable($1)operator(.)ident(downcase)operator(])
+ reserved(return) reserved(unless) ident(val)
+ ident(elem)operator([)symbol(:mon)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%C)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(elem)operator([)symbol(:cent)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%c)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%a %b %e %H:%M:%S %Y)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%D)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%m/%d/%y)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%d)delimiter(')>operator(,) string<delimiter(')content(%e)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content( ?()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(31)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:mday)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%F)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%Y-%m-%d)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%G)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([-+]?)char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(elem)operator([)symbol(:cwyear)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%g)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(99)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:cwyear)operator(]) operator(=) ident(val)
+ ident(elem)operator([)symbol(:cent)operator(]) operator(||)operator(=) reserved(if) ident(val) operator(>)operator(=) integer(69) reserved(then) integer(19) reserved(else) integer(20) reserved(end)
+ reserved(when) string<delimiter(')content(%H)delimiter(')>operator(,) string<delimiter(')content(%k)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content( ?()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(24)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:hour)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%I)delimiter(')>operator(,) string<delimiter(')content(%l)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content( ?()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(12)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:hour)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%j)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(366)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:yday)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%M)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(59)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:min)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%m)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(12)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:mon)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%n)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content( )delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%p)delimiter(')>operator(,) string<delimiter(')content(%P)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([ap]\)(?:m)char(\\b)content(|)char(\\.)content(m)char(\\.)content(\))delimiter(/)modifier(io)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(elem)operator([)symbol(:merid)operator(]) operator(=) reserved(if) global_variable($1)operator(.)ident(downcase) operator(==) string<delimiter(')content(a)delimiter(')> reserved(then) integer(0) reserved(else) integer(12) reserved(end)
+ reserved(when) string<delimiter(')content(%R)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%H:%M)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%r)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%I:%M:%S %p)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%S)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(60)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:sec)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%s)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(elem)operator([)symbol(:seconds)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%T)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%H:%M:%S)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%t)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content( )delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%U)delimiter(')>operator(,) string<delimiter(')content(%W)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(53)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)reserved(if) ident(c) operator(==) string<delimiter(')content(%U)delimiter(')> reserved(then) symbol(:wnum0) reserved(else) symbol(:wnum1) reserved(end)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%u)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(7)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:cwday)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%V)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(1)operator(..)integer(53)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:cweek)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%v)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%e-%b-%Y)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%w)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(6)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:wday)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%X)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%H:%M:%S)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%x)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%m/%d/%y)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%Y)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([-+]?)char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(elem)operator([)symbol(:year)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%y)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ reserved(return) reserved(unless) operator(()integer(0)operator(..)integer(99)operator(\)) operator(===) ident(val)
+ ident(elem)operator([)symbol(:year)operator(]) operator(=) ident(val)
+ ident(elem)operator([)symbol(:cent)operator(]) operator(||)operator(=) reserved(if) ident(val) operator(>)operator(=) integer(69) reserved(then) integer(19) reserved(else) integer(20) reserved(end)
+ reserved(when) string<delimiter(')content(%Z)delimiter(')>operator(,) string<delimiter(')content(%z)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(([-+:a-z0-9]+(?:)char(\\s)content(+dst)char(\\b)content(\)?\))delimiter(/)modifier(io)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)
+ ident(elem)operator([)symbol(:zone)operator(]) operator(=) ident(val)
+ ident(offset) operator(=) ident(zone_to_diff)operator(()ident(val)operator(\))
+ ident(elem)operator([)symbol(:offset)operator(]) operator(=) ident(offset)
+ reserved(when) string<delimiter(')content(%%)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(%)delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%+)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%a %b %e %H:%M:%S %Z %Y)delimiter(')>operator(,) ident(elem)operator(\))
+comment(=begin
+ when '%.'
+ return unless str.sub!(/\\A(\\d+\)/o, ''\)
+ val = $1.to_i.to_r / (10**$1.size\)
+ elem[:sec_fraction] = val
+=end)
+ reserved(when) string<delimiter(')content(%1)delimiter(')>
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\A)content(()char(\\d)content(+\))delimiter(/)modifier(o)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ ident(val) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(elem)operator([)symbol(:jd)operator(]) operator(=) ident(val)
+ reserved(when) string<delimiter(')content(%2)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%Y-%j)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(when) string<delimiter(')content(%3)delimiter(')>
+ reserved(return) reserved(unless) ident(__strptime)operator(()ident(str)operator(,) string<delimiter(')content(%F)delimiter(')>operator(,) ident(elem)operator(\))
+ reserved(else)
+ reserved(return) reserved(unless) ident(str)operator(.)ident(sub!)operator(()constant(Regexp)operator(.)ident(new)operator(()string<delimiter(')char(\\\\)content(A)delimiter(')> operator(+) constant(Regexp)operator(.)ident(quote)operator(()ident(c)operator(\))operator(\))operator(,) string<delimiter(')delimiter(')>operator(\))
+ reserved(end)
+ reserved(end)
+
+ reserved(if) ident(cent) operator(=) ident(elem)operator(.)ident(delete)operator(()symbol(:cent)operator(\))
+ reserved(if) ident(elem)operator([)symbol(:cwyear)operator(])
+ ident(elem)operator([)symbol(:cwyear)operator(]) operator(+)operator(=) ident(cent) operator(*) integer(100)
+ reserved(end)
+ reserved(if) ident(elem)operator([)symbol(:year)operator(])
+ ident(elem)operator([)symbol(:year)operator(]) operator(+)operator(=) ident(cent) operator(*) integer(100)
+ reserved(end)
+ reserved(end)
+
+ reserved(if) ident(merid) operator(=) ident(elem)operator(.)ident(delete)operator(()symbol(:merid)operator(\))
+ reserved(if) ident(elem)operator([)symbol(:hour)operator(])
+ ident(elem)operator([)symbol(:hour)operator(]) operator(%=) integer(12)
+ ident(elem)operator([)symbol(:hour)operator(]) operator(+)operator(=) ident(merid)
+ reserved(end)
+ reserved(end)
+
+ ident(str)
+ reserved(end)
+
+ ident(private_class_method) symbol(:__strptime)
+
+ reserved(def) pre_constant(self)operator(.)ident(_strptime)operator(()ident(str)operator(,) ident(fmt)operator(=)string<delimiter(')content(%F)delimiter(')>operator(\))
+ ident(elem) operator(=) operator({)operator(})
+ ident(elem) reserved(if) ident(__strptime)operator(()ident(str)operator(.)ident(dup)operator(,) ident(fmt)operator(,) ident(elem)operator(\))
+ reserved(end)
+
+ constant(PARSE_MONTHPAT) operator(=) constant(ABBR_MONTHS)operator(.)ident(keys)operator(.)ident(join)operator(()string<delimiter(')content(|)delimiter(')>operator(\))
+ constant(PARSE_DAYPAT) operator(=) constant(ABBR_DAYS)operator(.) ident(keys)operator(.)ident(join)operator(()string<delimiter(')content(|)delimiter(')>operator(\))
+
+ reserved(def) pre_constant(self)operator(.)ident(_parse)operator(()ident(str)operator(,) ident(comp)operator(=)pre_constant(false)operator(\))
+ ident(str) operator(=) ident(str)operator(.)ident(dup)
+
+ ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content([^-+,.)char(\\/)content(:0-9a-z]+)delimiter(/)modifier(ino)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+
+ comment(# day)
+ reserved(if) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(()inline<delimiter(#{)constant(PARSE_DAYPAT)delimiter(})>content(\))char(\\S)content(*)delimiter(/)modifier(ino)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(wday) operator(=) constant(ABBR_DAYS)operator([)global_variable($1)operator(.)ident(downcase)operator(])
+ reserved(end)
+
+ comment(# time)
+ reserved(if) ident(str)operator(.)ident(sub!)operator(()
+ regexp<delimiter(/)content(()char(\\d)content(+\):()char(\\d)content(+\)
+ (?:
+ :()char(\\d)content(+\)(?:[,.]()char(\\d)content(*\)\)?
+ \)?
+ (?:
+ )char(\\s)content(*
+ ([ap]\)(?:m)char(\\b)content(|)char(\\.)content(m)char(\\.)content(\)
+ \)?
+ (?:
+ )char(\\s)content(*
+ (
+ [a-z]+(?:)char(\\s)content(+dst\)?)char(\\b)content(
+ |
+ [-+])char(\\d)content(+(?::?)char(\\d)content(+\)
+ \)
+ \)?
+ )delimiter(/)modifier(inox)>operator(,)
+ string<delimiter(')content( )delimiter(')>operator(\))
+ ident(hour) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(min) operator(=) global_variable($2)operator(.)ident(to_i)
+ ident(sec) operator(=) global_variable($3)operator(.)ident(to_i) reserved(if) global_variable($3)
+ reserved(if) global_variable($4)
+ ident(sec_fraction) operator(=) global_variable($4)operator(.)ident(to_i)operator(.)ident(to_r) operator(/) operator(()integer(10)operator(**)global_variable($4)operator(.)ident(size)operator(\))
+ reserved(end)
+
+ reserved(if) global_variable($5)
+ ident(hour) operator(%=) integer(12)
+ reserved(if) global_variable($5)operator(.)ident(downcase) operator(==) string<delimiter(')content(p)delimiter(')>
+ ident(hour) operator(+)operator(=) integer(12)
+ reserved(end)
+ reserved(end)
+
+ reserved(if) global_variable($6)
+ ident(zone) operator(=) global_variable($6)
+ reserved(end)
+ reserved(end)
+
+ comment(# eu)
+ reserved(if) ident(str)operator(.)ident(sub!)operator(()
+ regexp<delimiter(/)content(()char(\\d)content(+\))char(\\S)content(*
+ )char(\\s)content(+
+ ()inline<delimiter(#{)constant(PARSE_MONTHPAT)delimiter(})>content(\))char(\\S)content(*
+ (?:
+ )char(\\s)content(+
+ (-?)char(\\d)content(+\)
+ \)?
+ )delimiter(/)modifier(inox)>operator(,)
+ string<delimiter(')content( )delimiter(')>operator(\))
+ ident(mday) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(mon) operator(=) constant(ABBR_MONTHS)operator([)global_variable($2)operator(.)ident(downcase)operator(])
+
+ reserved(if) global_variable($3)
+ ident(year) operator(=) global_variable($3)operator(.)ident(to_i)
+ reserved(if) global_variable($3)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(end)
+ reserved(end)
+
+ comment(# us)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()
+ regexp<delimiter(/)content(()inline<delimiter(#{)constant(PARSE_MONTHPAT)delimiter(})>content(\))char(\\S)content(*
+ )char(\\s)content(+
+ ()char(\\d)content(+\))char(\\S)content(*
+ (?:
+ )char(\\s)content(+
+ (-?)char(\\d)content(+\)
+ \)?
+ )delimiter(/)modifier(inox)>operator(,)
+ string<delimiter(')content( )delimiter(')>operator(\))
+ ident(mon) operator(=) constant(ABBR_MONTHS)operator([)global_variable($1)operator(.)ident(downcase)operator(])
+ ident(mday) operator(=) global_variable($2)operator(.)ident(to_i)
+
+ reserved(if) global_variable($3)
+ ident(year) operator(=) global_variable($3)operator(.)ident(to_i)
+ reserved(if) global_variable($3)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(end)
+ reserved(end)
+
+ comment(# iso)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(([-+]?)char(\\d)content(+\)-()char(\\d)content(+\)-(-?)char(\\d)content(+\))delimiter(/)modifier(no)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(year) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(mon) operator(=) global_variable($2)operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($3)operator(.)ident(to_i)
+
+ reserved(if) global_variable($1)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(elsif) global_variable($3)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ ident(mday)operator(,) ident(mon)operator(,) ident(year) operator(=) ident(year)operator(,) ident(mon)operator(,) ident(mday)
+ reserved(end)
+
+ comment(# jis)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(([MTSH]\)()char(\\d)content(+\))char(\\.)content(()char(\\d)content(+\))char(\\.)content(()char(\\d)content(+\))delimiter(/)modifier(ino)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(e) operator(=) operator({) string<delimiter(')content(m)delimiter(')>operator(=)operator(>)integer(1867)operator(,)
+ string<delimiter(')content(t)delimiter(')>operator(=)operator(>)integer(1911)operator(,)
+ string<delimiter(')content(s)delimiter(')>operator(=)operator(>)integer(1925)operator(,)
+ string<delimiter(')content(h)delimiter(')>operator(=)operator(>)integer(1988)
+ operator(})operator([)global_variable($1)operator(.)ident(downcase)operator(])
+ ident(year) operator(=) global_variable($2)operator(.)ident(to_i) operator(+) ident(e)
+ ident(mon) operator(=) global_variable($3)operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($4)operator(.)ident(to_i)
+
+ comment(# vms)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content((-?)char(\\d)content(+\)-()inline<delimiter(#{)constant(PARSE_MONTHPAT)delimiter(})>content(\)[^-]*-(-?)char(\\d)content(+\))delimiter(/)modifier(ino)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(mday) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(mon) operator(=) constant(ABBR_MONTHS)operator([)global_variable($2)operator(.)ident(downcase)operator(])
+ ident(year) operator(=) global_variable($3)operator(.)ident(to_i)
+
+ reserved(if) global_variable($1)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ ident(year)operator(,) ident(mon)operator(,) ident(mday) operator(=) ident(mday)operator(,) ident(mon)operator(,) ident(year)
+ reserved(elsif) global_variable($3)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(end)
+
+ comment(# sla)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(%r|)content((-?)char(\\d)content(+\)/()char(\\d)content(+\)(?:/(-?)char(\\d)content(+\)\)?)delimiter(|)modifier(no)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(mon) operator(=) global_variable($1)operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($2)operator(.)ident(to_i)
+
+ reserved(if) global_variable($3)
+ ident(year) operator(=) global_variable($3)operator(.)ident(to_i)
+ reserved(if) global_variable($3)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(end)
+ reserved(end)
+
+ reserved(if) global_variable($3) operator(&&) global_variable($1)operator(.)ident(size) operator(>) integer(2)
+ ident(comp) operator(=) pre_constant(false)
+ ident(year)operator(,) ident(mon)operator(,) ident(mday) operator(=) ident(mon)operator(,) ident(mday)operator(,) ident(year)
+ reserved(end)
+
+ comment(# ddd)
+ reserved(elsif) ident(str)operator(.)ident(sub!)operator(()
+ regexp<delimiter(/)content(([-+]?\)()char(\\d)content({4,14}\)
+ (?:
+ )char(\\s)content(*
+ T?
+ )char(\\s)content(*
+ ()char(\\d)content({2,6}\)(?:[,.]()char(\\d)content(*\)\)?
+ \)?
+ (?:
+ )char(\\s)content(*
+ (
+ Z
+ |
+ [-+])char(\\d)content({2,4}
+ \)
+ )char(\\b)content(
+ \)?
+ )delimiter(/)modifier(inox)>operator(,)
+ string<delimiter(')content( )delimiter(')>operator(\))
+ reserved(case) global_variable($2)operator(.)ident(size)
+ reserved(when) integer(4)
+ ident(mon) operator(=) global_variable($2)operator([) integer(0)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($2)operator([) integer(2)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ reserved(when) integer(6)
+ ident(year) operator(=) operator(()global_variable($1) operator(+) global_variable($2)operator([) integer(0)operator(,) integer(2)operator(])operator(\))operator(.)ident(to_i)
+ ident(mon) operator(=) global_variable($2)operator([) integer(2)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($2)operator([) integer(4)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ reserved(when) integer(8)operator(,) integer(10)operator(,) integer(12)operator(,) integer(14)
+ ident(year) operator(=) operator(()global_variable($1) operator(+) global_variable($2)operator([) integer(0)operator(,) integer(4)operator(])operator(\))operator(.)ident(to_i)
+ ident(mon) operator(=) global_variable($2)operator([) integer(4)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ ident(mday) operator(=) global_variable($2)operator([) integer(6)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ ident(hour) operator(=) global_variable($2)operator([) integer(8)operator(,) integer(2)operator(])operator(.)ident(to_i) reserved(if) global_variable($2)operator(.)ident(size) operator(>)operator(=) integer(10)
+ ident(min) operator(=) global_variable($2)operator([)integer(10)operator(,) integer(2)operator(])operator(.)ident(to_i) reserved(if) global_variable($2)operator(.)ident(size) operator(>)operator(=) integer(12)
+ ident(sec) operator(=) global_variable($2)operator([)integer(12)operator(,) integer(2)operator(])operator(.)ident(to_i) reserved(if) global_variable($2)operator(.)ident(size) operator(>)operator(=) integer(14)
+ ident(comp) operator(=) pre_constant(false)
+ reserved(end)
+ reserved(if) global_variable($3)
+ reserved(case) global_variable($3)operator(.)ident(size)
+ reserved(when) integer(2)operator(,) integer(4)operator(,) integer(6)
+ ident(hour) operator(=) global_variable($3)operator([) integer(0)operator(,) integer(2)operator(])operator(.)ident(to_i)
+ ident(min) operator(=) global_variable($3)operator([) integer(2)operator(,) integer(2)operator(])operator(.)ident(to_i) reserved(if) global_variable($3)operator(.)ident(size) operator(>)operator(=) integer(4)
+ ident(sec) operator(=) global_variable($3)operator([) integer(4)operator(,) integer(2)operator(])operator(.)ident(to_i) reserved(if) global_variable($3)operator(.)ident(size) operator(>)operator(=) integer(6)
+ reserved(end)
+ reserved(end)
+ reserved(if) global_variable($4)
+ ident(sec_fraction) operator(=) global_variable($4)operator(.)ident(to_i)operator(.)ident(to_r) operator(/) operator(()integer(10)operator(**)global_variable($4)operator(.)ident(size)operator(\))
+ reserved(end)
+ reserved(if) global_variable($5)
+ ident(zone) operator(=) global_variable($5)
+ reserved(end)
+ reserved(end)
+
+ reserved(if) ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\b)content((bc)char(\\b)content(|bce)char(\\b)content(|b)char(\\.)content(c)char(\\.)content(|b)char(\\.)content(c)char(\\.)content(e)char(\\.)content(\))delimiter(/)modifier(ino)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ reserved(if) ident(year)
+ ident(year) operator(=) operator(-)ident(year) operator(+) integer(1)
+ reserved(end)
+ reserved(end)
+
+ reserved(if) ident(comp) reserved(and) ident(year)
+ reserved(if) ident(year) operator(>)operator(=) integer(0) reserved(and) ident(year) operator(<=) integer(99)
+ reserved(if) ident(year) operator(>)operator(=) integer(69)
+ ident(year) operator(+)operator(=) integer(1900)
+ reserved(else)
+ ident(year) operator(+)operator(=) integer(2000)
+ reserved(end)
+ reserved(end)
+ reserved(end)
+
+ ident(elem) operator(=) operator({)operator(})
+ ident(elem)operator([)symbol(:year)operator(]) operator(=) ident(year) reserved(if) ident(year)
+ ident(elem)operator([)symbol(:mon)operator(]) operator(=) ident(mon) reserved(if) ident(mon)
+ ident(elem)operator([)symbol(:mday)operator(]) operator(=) ident(mday) reserved(if) ident(mday)
+ ident(elem)operator([)symbol(:hour)operator(]) operator(=) ident(hour) reserved(if) ident(hour)
+ ident(elem)operator([)symbol(:min)operator(]) operator(=) ident(min) reserved(if) ident(min)
+ ident(elem)operator([)symbol(:sec)operator(]) operator(=) ident(sec) reserved(if) ident(sec)
+ ident(elem)operator([)symbol(:sec_fraction)operator(]) operator(=) ident(sec_fraction) reserved(if) ident(sec_fraction)
+ ident(elem)operator([)symbol(:zone)operator(]) operator(=) ident(zone) reserved(if) ident(zone)
+ ident(offset) operator(=) ident(zone_to_diff)operator(()ident(zone)operator(\)) reserved(if) ident(zone)
+ ident(elem)operator([)symbol(:offset)operator(]) operator(=) ident(offset) reserved(if) ident(offset)
+ ident(elem)operator([)symbol(:wday)operator(]) operator(=) ident(wday) reserved(if) ident(wday)
+ ident(elem)
+ reserved(end)
+
+ reserved(def) pre_constant(self)operator(.)ident(zone_to_diff)operator(()ident(str)operator(\))
+ ident(abb)operator(,) ident(dst) operator(=) ident(str)operator(.)ident(downcase)operator(.)ident(split)operator(()regexp<delimiter(/)char(\\s)content(+)delimiter(/)modifier(o)>operator(,) integer(2)operator(\))
+ reserved(if) constant(ZONES)operator(.)ident(include?)operator(()ident(abb)operator(\))
+ ident(offset) operator(=) constant(ZONES)operator([)ident(abb)operator(])
+ ident(offset) operator(+)operator(=) integer(3600) reserved(if) ident(dst)
+ reserved(elsif) regexp<delimiter(/)char(\\A)content(([-+]\)()char(\\d)content({2}\):?()char(\\d)content({2}\)?)char(\\Z)delimiter(/)modifier(no)> operator(=)operator(~) ident(str)
+ ident(offset) operator(=) global_variable($2)operator(.)ident(to_i) operator(*) integer(3600) operator(+) global_variable($3)operator(.)ident(to_i) operator(*) integer(60)
+ ident(offset) operator(*)operator(=) operator(-)integer(1) reserved(if) global_variable($1) operator(==) string<delimiter(')content(-)delimiter(')>
+ reserved(end)
+ ident(offset)
+ reserved(end)
+
+ reserved(def) method(strftime)operator(()ident(fmt)operator(=)string<delimiter(')content(%F)delimiter(')>operator(\))
+ ident(o) operator(=) string<delimiter(')delimiter(')>
+ ident(fmt)operator(.)ident(scan)operator(()regexp<delimiter(/)content(%[EO]?.|.)delimiter(/)modifier(o)>operator(\)) reserved(do) operator(|)ident(c)operator(|)
+ ident(cc) operator(=) ident(c)operator(.)ident(sub)operator(()regexp<delimiter(/)content(^%[EO]?(.\)$)delimiter(/)modifier(o)>operator(,) string<delimiter(')content(%)char(\\\\)content(1)delimiter(')>operator(\))
+ reserved(case) ident(cc)
+ reserved(when) string<delimiter(')content(%A)delimiter(')>operator(;) ident(o) operator(<<) constant(DAYNAMES)operator([)ident(wday)operator(])
+ reserved(when) string<delimiter(')content(%a)delimiter(')>operator(;) ident(o) operator(<<) constant(ABBR_DAYNAMES)operator([)ident(wday)operator(])
+ reserved(when) string<delimiter(')content(%B)delimiter(')>operator(;) ident(o) operator(<<) constant(MONTHNAMES)operator([)ident(mon)operator(])
+ reserved(when) string<delimiter(')content(%b)delimiter(')>operator(;) ident(o) operator(<<) constant(ABBR_MONTHNAMES)operator([)ident(mon)operator(])
+ reserved(when) string<delimiter(')content(%C)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) operator(()ident(year) operator(/) float(100.0)operator(\))operator(.)ident(floor) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%c)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%a %b %e %H:%M:%S %Y)delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%D)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%m/%d/%y)delimiter(')>operator(\)) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%d)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(mday)
+ reserved(when) string<delimiter(')content(%e)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%2d)delimiter(')> operator(%) ident(mday)
+ reserved(when) string<delimiter(')content(%F)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%Y-%m-%d)delimiter(')>operator(\)) comment(# ID)
+ reserved(when) string<delimiter(')content(%G)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%.4d)delimiter(')> operator(%) ident(cwyear) comment(# ID)
+ reserved(when) string<delimiter(')content(%g)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) operator(()ident(cwyear) operator(%) integer(100)operator(\)) comment(# ID)
+ reserved(when) string<delimiter(')content(%H)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(hour)
+ reserved(when) string<delimiter(')content(%h)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%b)delimiter(')>operator(\)) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%I)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) operator(()operator(()ident(hour) operator(%) integer(12)operator(\))operator(.)ident(nonzero?) reserved(or) integer(12)operator(\))
+ reserved(when) string<delimiter(')content(%j)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%03d)delimiter(')> operator(%) ident(yday)
+ reserved(when) string<delimiter(')content(%k)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%2d)delimiter(')> operator(%) ident(hour) comment(# AR,TZ,GL)
+ reserved(when) string<delimiter(')content(%l)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%2d)delimiter(')> operator(%) operator(()operator(()ident(hour) operator(%) integer(12)operator(\))operator(.)ident(nonzero?) reserved(or) integer(12)operator(\)) comment(# AR,TZ,GL)
+ reserved(when) string<delimiter(')content(%M)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(min)
+ reserved(when) string<delimiter(')content(%m)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(mon)
+ reserved(when) string<delimiter(')content(%n)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(")char(\\n)delimiter(")> comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%P)delimiter(')>operator(;) ident(o) operator(<<) reserved(if) ident(hour) operator(<) integer(12) reserved(then) string<delimiter(')content(am)delimiter(')> reserved(else) string<delimiter(')content(pm)delimiter(')> reserved(end) comment(# GL)
+ reserved(when) string<delimiter(')content(%p)delimiter(')>operator(;) ident(o) operator(<<) reserved(if) ident(hour) operator(<) integer(12) reserved(then) string<delimiter(')content(AM)delimiter(')> reserved(else) string<delimiter(')content(PM)delimiter(')> reserved(end)
+ reserved(when) string<delimiter(')content(%R)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%H:%M)delimiter(')>operator(\)) comment(# ID)
+ reserved(when) string<delimiter(')content(%r)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%I:%M:%S %p)delimiter(')>operator(\)) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%S)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(sec)
+ reserved(when) string<delimiter(')content(%s)delimiter(')> comment(# TZ,GL)
+ ident(d) operator(=) ident(ajd) operator(-) pre_constant(self)operator(.)ident(class)operator(.)ident(jd_to_ajd)operator(()pre_constant(self)operator(.)ident(class)operator(.)ident(civil_to_jd)operator(()integer(1970)operator(,)integer(1)operator(,)integer(1)operator(\))operator(,) integer(0)operator(\))
+ ident(s) operator(=) operator(()ident(d) operator(*) integer(86400)operator(\))operator(.)ident(to_i)
+ ident(o) operator(<<) string<delimiter(')content(%d)delimiter(')> operator(%) ident(s)
+ reserved(when) string<delimiter(')content(%T)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%H:%M:%S)delimiter(')>operator(\)) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%t)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(")char(\\t)delimiter(")> comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%U)delimiter(')>operator(,) string<delimiter(')content(%W)delimiter(')>
+ ident(a) operator(=) pre_constant(self)operator(.)ident(class)operator(.)ident(civil_to_jd)operator(()ident(year)operator(,) integer(1)operator(,) integer(1)operator(,) ident(ns?)operator(\)) operator(+) integer(6)
+ ident(k) operator(=) reserved(if) ident(c) operator(==) string<delimiter(')content(%U)delimiter(')> reserved(then) integer(0) reserved(else) integer(1) reserved(end)
+ ident(w) operator(=) operator(()ident(jd) operator(-) operator(()ident(a) operator(-) operator(()operator(()ident(a) operator(-) ident(k)operator(\)) operator(+) integer(1)operator(\)) operator(%) integer(7)operator(\)) operator(+) integer(7)operator(\)) operator(/) integer(7)
+ ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(w)
+ reserved(when) string<delimiter(')content(%u)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%d)delimiter(')> operator(%) ident(cwday) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%V)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(cweek) comment(# P2,ID)
+ reserved(when) string<delimiter(')content(%v)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%e-%b-%Y)delimiter(')>operator(\)) comment(# AR,TZ)
+ reserved(when) string<delimiter(')content(%w)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%d)delimiter(')> operator(%) ident(wday)
+ reserved(when) string<delimiter(')content(%X)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%H:%M:%S)delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%x)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%m/%d/%y)delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%Y)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%.4d)delimiter(')> operator(%) ident(year)
+ reserved(when) string<delimiter(')content(%y)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) operator(()ident(year) operator(%) integer(100)operator(\))
+ reserved(when) string<delimiter(')content(%Z)delimiter(')>operator(;) ident(o) operator(<<) operator(()reserved(if) ident(offset)operator(.)ident(zero?) reserved(then) string<delimiter(')content(Z)delimiter(')> reserved(else) ident(strftime)operator(()string<delimiter(')content(%z)delimiter(')>operator(\)) reserved(end)operator(\))
+ reserved(when) string<delimiter(')content(%z)delimiter(')> comment(# ID)
+ ident(o) operator(<<) reserved(if) ident(offset) operator(<) integer(0) reserved(then) string<delimiter(')content(-)delimiter(')> reserved(else) string<delimiter(')content(+)delimiter(')> reserved(end)
+ ident(of) operator(=) ident(offset)operator(.)ident(abs)
+ ident(hh)operator(,) ident(fr) operator(=) ident(of)operator(.)ident(divmod)operator(()integer(1)operator(.)ident(to_r)operator(/)integer(24)operator(\))
+ ident(mm) operator(=) ident(fr) operator(/) operator(()integer(1)operator(.)ident(to_r)operator(/)integer(1440)operator(\))
+ ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(hh)
+ ident(o) operator(<<) string<delimiter(')content(%02d)delimiter(')> operator(%) ident(mm)
+ reserved(when) string<delimiter(')content(%%)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%)delimiter(')>
+ reserved(when) string<delimiter(')content(%+)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%a %b %e %H:%M:%S %Z %Y)delimiter(')>operator(\)) comment(# TZ)
+comment(=begin
+ when '%.'
+ o << '%06d' % (sec_fraction / (1.to_r/86400/(10**6\)\)\)
+=end)
+ reserved(when) string<delimiter(')content(%1)delimiter(')>operator(;) ident(o) operator(<<) string<delimiter(')content(%d)delimiter(')> operator(%) ident(jd)
+ reserved(when) string<delimiter(')content(%2)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%Y-%j)delimiter(')>operator(\))
+ reserved(when) string<delimiter(')content(%3)delimiter(')>operator(;) ident(o) operator(<<) ident(strftime)operator(()string<delimiter(')content(%Y-%m-%d)delimiter(')>operator(\))
+ reserved(else)operator(;) ident(o) operator(<<) ident(c)
+ reserved(end)
+ reserved(end)
+ ident(o)
+ reserved(end)
+
+comment(# alias_method :format, :strftime)
+
+ reserved(def) method(asctime)operator(()operator(\)) ident(strftime)operator(()string<delimiter(')content(%c)delimiter(')>operator(\)) reserved(end)
+
+ ident(alias_method) symbol(:ctime)operator(,) symbol(:asctime)
+
+reserved(end)
+
+reserved(class) class(DateTime) operator(<) constant(Date)
+
+ reserved(def) pre_constant(self)operator(.)ident(_strptime)operator(()ident(str)operator(,) ident(fmt)operator(=)string<delimiter(')content(%FT%T%Z)delimiter(')>operator(\))
+ reserved(super)operator(()ident(str)operator(,) ident(fmt)operator(\))
+ reserved(end)
+
+ reserved(def) method(strftime)operator(()ident(fmt)operator(=)string<delimiter(')content(%FT%T%Z)delimiter(')>operator(\))
+ reserved(super)operator(()ident(fmt)operator(\))
+ reserved(end)
+
+reserved(end)
+
+ident(require) string<delimiter(')content(generator)delimiter(')>
+ident(a) operator(=) operator([)integer(2)operator(,) integer(3)operator(,) integer(5)operator(,) integer(7)operator(,) integer(11)operator(])
+ident(b) operator(=) string<delimiter(%w#)content(h a l l o)delimiter(#)>
+constant(SyncEnumerator)operator(.)ident(new)operator(()ident(a)operator(,) ident(b)operator(\))operator(.)ident(each) operator({) operator(|)ident(i)operator(,) ident(j)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(i)delimiter(})>content( & )inline<delimiter(#{)ident(j)delimiter(})>delimiter(")>
+operator(})
+
+reserved(class) class(Signature) operator(<) constant(Array)
+ reserved(def) method(===) ident(x)
+ ident(x)operator(.)ident(kind_of?) constant(Array) reserved(and) ident(zip)operator(()ident(x)operator(\))operator(.)ident(all?) operator({) operator(|)ident(me)operator(,) ident(it)operator(|) ident(me) operator(===) ident(it) operator(})
+ reserved(end)
+reserved(end)
+
+reserved(module) class(Chess)
+
+ constant(BOARD_RANGE) operator(=) integer(1)operator(..)integer(8)
+
+ reserved(class) class(Position)
+
+ ident(attr_reader) symbol(:x)operator(,) symbol(:y)
+
+ reserved(def) method(initialize) operator(*)ident(args)
+ instance_variable(@x)operator(,) instance_variable(@y) operator(=) reserved(case) ident(args)
+ reserved(when) constant(Signature)operator([)constant(Fixnum)operator(,) constant(Fixnum)operator(])
+ ident(args)
+ reserved(when) constant(Signature)operator([)constant(String)operator(])
+ constant(Position)operator(.)ident(decode) ident(args)operator(.)ident(first)
+ reserved(else)
+ ident(raise) constant(ArgumentError)operator(,) string<delimiter(')content(wrong number of arguments(one String or two fixnums\))delimiter(')>
+ reserved(end)
+ ident(raise) constant(RuntimeError)operator(,) string<delimiter(')content(%p is out of the chess board)delimiter(')> operator(%) pre_constant(self) reserved(unless) constant(Position)operator(.)ident(valid?) instance_variable(@x)operator(,) instance_variable(@y)
+ reserved(end)
+
+ reserved(def) method(inspect)
+ string<delimiter(')content(Position(%p, %p\))delimiter(')> operator(%) operator([)ident(x)operator(,) ident(y)operator(])
+ reserved(end)
+
+ reserved(def) constant(Position)operator(.)ident(decode) ident(pos)
+ ident(x)operator(,) ident(y) operator(=) ident(pos)operator(.)ident(split)operator(()string<delimiter(')delimiter(')>operator(\))
+ reserved(return) ident(x)operator(.)ident(upcase)operator([)integer(0)operator(]) operator(-) integer(?A) operator(+) integer(1)operator(,) instance_variable(@y) operator(=) ident(y)operator([)integer(0)operator(]) operator(-) integer(?0)
+ reserved(end)
+
+ reserved(def) constant(Position)operator(.)ident(valid?) ident(x)operator(,) ident(y)
+ constant(BOARD_RANGE)operator(.)ident(include?) ident(x) reserved(and) constant(BOARD_RANGE)operator(.)ident(include?) ident(y)
+ reserved(end)
+ reserved(end)
+
+reserved(end)
+
+ident(p) constant(Chess)operator(::)constant(Position)operator(.)ident(new)operator(()string<delimiter(')content(H3)delimiter(')>operator(\))
+constant(SuperString) operator(=) constant(Class)operator(.)ident(new) constant(String)
+ident(p) constant(Chess)operator(::)constant(Position)operator(.)ident(new)operator(()constant(SuperString)operator(.)ident(new)operator(()string<delimiter(')content(C5)delimiter(')>operator(\))operator(\))
+ident(p) constant(Chess)operator(::)constant(Position)operator(.)ident(new)operator(()integer(3)operator(,) integer(6)operator(\))
+ident(p) constant(Chess)operator(::)constant(Position)operator(.)ident(new)operator(()integer(3)operator(,) integer(9)operator(\))
+
+ident(require) string<delimiter(')content(grammar)delimiter(')>
+
+reserved(def) method(test_grammars)
+ operator([)string<delimiter(<<EOG1)>operator(,) string<delimiter(<<EOG2)>operator(,) string<delimiter(<<EOG3)>operator(,)operator(])operator(.)ident(map) operator({) operator(|)ident(g)operator(|) constant(Grammar)operator(.)ident(new) ident(g) operator(})string<content(
+Z --> S
+S --> Sb
+S --> bAa
+A --> aSc
+A --> a
+A --> aSb)delimiter(
+EOG1)>string<content(
+
+C --> d
+C --> ABC
+B -->
+B --> c
+A --> B
+A --> a)delimiter(
+EOG2)>string<content(
+
+E - TD
+D - pTD
+D -
+T - FS
+S - uFS
+S -
+F - aEz
+F - i)delimiter(
+EOG3)>
+reserved(end)
+
+global_variable($trace) operator(=) pre_constant(false)
+ident(test_grammars)operator(.)ident(each_with_index) reserved(do) operator(|)ident(g)operator(,) ident(i)operator(|)
+ ident(puts) string<delimiter(")content(Grammar )inline<delimiter(#{)ident(i)delimiter(})>content( is )inline<delimiter(#{)string<delimiter(')content(not )delimiter(')> reserved(if) ident(g)operator(.)ident(ll1?)delimiter(})>content(LL(1\).)delimiter(")>
+reserved(end)
diff --git a/test/ruby/class.in.rb b/test/ruby/class.in.rb new file mode 100644 index 0000000..b8d0bca --- /dev/null +++ b/test/ruby/class.in.rb @@ -0,0 +1,83 @@ +$: << File.dirname(__FILE__) + '/..'
+require 'coderay'
+CodeRay::Encoders[:tokens]
+CodeRay::Encoders[:html]
+
+require 'test/unit'
+include Test::Unit
+
+class CodeRaySuite < TestCase
+
+ def self.dir &block
+ @dir ||= File.dirname(@file)
+ if block
+ Dir.chdir @dir, &block
+ end
+ @dir
+ end
+
+ def dir &block
+ self.class.dir &block
+ end
+
+ def extension
+ 'in.' + self.class::EXTENSION
+ end
+
+ def lang
+ self.class::LANG
+ end
+
+ def test_ALL
+ CodeRay::Scanners.load lang
+ tokenizer = CodeRay.tokens
+ highlighter = CodeRay.html
+
+ dir do
+ for input in Dir["*.#{extension}"]
+ name = File.basename(input, ".#{extension}")
+ output = name + '.out.tok'
+ code = File.read(input)
+
+ computed = tokenizer.encode code, lang
+
+ if File.exist? output
+ expected = File.read output
+ assert_equal(expected, computed)
+ else
+ File.open(output, 'w') do |f| f.write computed end
+ puts "New test: #{output}"
+ end
+
+ highlighted = highlighter.highlight_page code, lang
+ File.open(name + '.html', 'w') do |f| f.write highlighted end
+ end
+ end
+ end
+
+end
+
+require 'test/unit/testsuite'
+$suite = TestSuite.new
+
+def load_suite name
+ begin
+ require name + '/suite.rb'
+ rescue LoadError
+ $stderr.puts <<-ERR
+
+!! Folder #{File.split(__FILE__).first + '/' + name} not found
+
+ ERR
+ false
+ end
+end
+
+if subsuite = ARGV.first
+ load_suite(subsuite) or exit
+else
+ Dir['*/'].each { |suite| load_suite suite }
+end
+
+require 'test/unit/ui/console/testrunner'
+UI::Console::TestRunner.run $suite
diff --git a/test/ruby/class.out.raydebug b/test/ruby/class.out.raydebug new file mode 100644 index 0000000..b9b57a7 --- /dev/null +++ b/test/ruby/class.out.raydebug @@ -0,0 +1,83 @@ +global_variable($:) operator(<<) constant(File)operator(.)ident(dirname)operator(()pre_constant(__FILE__)operator(\)) operator(+) string<delimiter(')content(/..)delimiter(')>
+ident(require) string<delimiter(')content(coderay)delimiter(')>
+constant(CodeRay)operator(::)constant(Encoders)operator([)symbol(:tokens)operator(])
+constant(CodeRay)operator(::)constant(Encoders)operator([)symbol(:html)operator(])
+
+ident(require) string<delimiter(')content(test/unit)delimiter(')>
+ident(include) constant(Test)operator(::)constant(Unit)
+
+reserved(class) class(CodeRaySuite) operator(<) constant(TestCase)
+
+ reserved(def) pre_constant(self)operator(.)ident(dir) operator(&)ident(block)
+ instance_variable(@dir) operator(||)operator(=) constant(File)operator(.)ident(dirname)operator(()instance_variable(@file)operator(\))
+ reserved(if) ident(block)
+ constant(Dir)operator(.)ident(chdir) instance_variable(@dir)operator(,) operator(&)ident(block)
+ reserved(end)
+ instance_variable(@dir)
+ reserved(end)
+
+ reserved(def) method(dir) operator(&)ident(block)
+ pre_constant(self)operator(.)ident(class)operator(.)ident(dir) operator(&)ident(block)
+ reserved(end)
+
+ reserved(def) method(extension)
+ string<delimiter(')content(in.)delimiter(')> operator(+) pre_constant(self)operator(.)ident(class)operator(::)constant(EXTENSION)
+ reserved(end)
+
+ reserved(def) method(lang)
+ pre_constant(self)operator(.)ident(class)operator(::)constant(LANG)
+ reserved(end)
+
+ reserved(def) method(test_ALL)
+ constant(CodeRay)operator(::)constant(Scanners)operator(.)ident(load) ident(lang)
+ ident(tokenizer) operator(=) constant(CodeRay)operator(.)ident(tokens)
+ ident(highlighter) operator(=) constant(CodeRay)operator(.)ident(html)
+
+ ident(dir) reserved(do)
+ reserved(for) ident(input) reserved(in) constant(Dir)operator([)string<delimiter(")content(*.)inline<delimiter(#{)ident(extension)delimiter(})>delimiter(")>operator(])
+ ident(name) operator(=) constant(File)operator(.)ident(basename)operator(()ident(input)operator(,) string<delimiter(")content(.)inline<delimiter(#{)ident(extension)delimiter(})>delimiter(")>operator(\))
+ ident(output) operator(=) ident(name) operator(+) string<delimiter(')content(.out.tok)delimiter(')>
+ ident(code) operator(=) constant(File)operator(.)ident(read)operator(()ident(input)operator(\))
+
+ ident(computed) operator(=) ident(tokenizer)operator(.)ident(encode) ident(code)operator(,) ident(lang)
+
+ reserved(if) constant(File)operator(.)ident(exist?) ident(output)
+ ident(expected) operator(=) constant(File)operator(.)ident(read) ident(output)
+ ident(assert_equal)operator(()ident(expected)operator(,) ident(computed)operator(\))
+ reserved(else)
+ constant(File)operator(.)ident(open)operator(()ident(output)operator(,) string<delimiter(')content(w)delimiter(')>operator(\)) reserved(do) operator(|)ident(f)operator(|) ident(f)operator(.)ident(write) ident(computed) reserved(end)
+ ident(puts) string<delimiter(")content(New test: )inline<delimiter(#{)ident(output)delimiter(})>delimiter(")>
+ reserved(end)
+
+ ident(highlighted) operator(=) ident(highlighter)operator(.)ident(highlight_page) ident(code)operator(,) ident(lang)
+ constant(File)operator(.)ident(open)operator(()ident(name) operator(+) string<delimiter(')content(.html)delimiter(')>operator(,) string<delimiter(')content(w)delimiter(')>operator(\)) reserved(do) operator(|)ident(f)operator(|) ident(f)operator(.)ident(write) ident(highlighted) reserved(end)
+ reserved(end)
+ reserved(end)
+ reserved(end)
+
+reserved(end)
+
+ident(require) string<delimiter(')content(test/unit/testsuite)delimiter(')>
+global_variable($suite) operator(=) constant(TestSuite)operator(.)ident(new)
+
+reserved(def) method(load_suite) ident(name)
+ reserved(begin)
+ ident(require) ident(name) operator(+) string<delimiter(')content(/suite.rb)delimiter(')>
+ reserved(rescue) constant(LoadError)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(<<-ERR)>string<content(
+
+!! Folder )inline<delimiter(#{)constant(File)operator(.)ident(split)operator(()pre_constant(__FILE__)operator(\))operator(.)ident(first) operator(+) string<delimiter(')content(/)delimiter(')> operator(+) ident(name)delimiter(})>content( not found
+ )delimiter(
+ ERR)>
+ pre_constant(false)
+ reserved(end)
+reserved(end)
+
+reserved(if) ident(subsuite) operator(=) pre_constant(ARGV)operator(.)ident(first)
+ ident(load_suite)operator(()ident(subsuite)operator(\)) reserved(or) ident(exit)
+reserved(else)
+ constant(Dir)operator([)string<delimiter(')content(*/)delimiter(')>operator(])operator(.)ident(each) operator({) operator(|)ident(suite)operator(|) ident(load_suite) ident(suite) operator(})
+reserved(end)
+
+ident(require) string<delimiter(')content(test/unit/ui/console/testrunner)delimiter(')>
+constant(UI)operator(::)constant(Console)operator(::)constant(TestRunner)operator(.)ident(run) global_variable($suite)
diff --git a/test/ruby/comment.in.rb b/test/ruby/comment.in.rb new file mode 100644 index 0000000..d0dea65 --- /dev/null +++ b/test/ruby/comment.in.rb @@ -0,0 +1,17 @@ +=begin test
+=end test
+
+bla
+
+ =begin
+
+ __END__
+
+
+__END__
+#CODE
+
+mangawobeegee
+
+#test\
+dasd
diff --git a/test/ruby/comment.out.raydebug b/test/ruby/comment.out.raydebug new file mode 100644 index 0000000..5e03975 --- /dev/null +++ b/test/ruby/comment.out.raydebug @@ -0,0 +1,17 @@ +comment(=begin test
+=end test)
+
+ident(bla)
+
+ operator(=)reserved(begin)
+
+ ident(__END__)
+
+
+comment(__END__
+)comment(#CODE)
+
+ident(mangawobeegee)
+
+comment(#test\\)
+ident(dasd)
diff --git a/test/ruby/evil.in.rb b/test/ruby/evil.in.rb new file mode 100644 index 0000000..877a586 --- /dev/null +++ b/test/ruby/evil.in.rb @@ -0,0 +1,1123 @@ +p(String *Class)
+class String
+class Class
+end
+end
+#def String(x) x.to_s end #it's already built-in. duh!
+def String.*(right) [self,right] end
+def String.<<(right) [self,:<<,right] end
+def String./(right) [self,:/,right] end
+def String.[](right) [self,:[],right] end
+p(String::Class)
+p(String:: Class)
+p(String ::Class)
+p(String :: Class)
+p(String<<Class)
+p(String<< Class)
+p(String <<Class)
+sgsdfgf
+Class
+p(String << Class)
+p(String/Class)
+p(String/ Class)
+p(String /Class/)
+p(String / Class) #borken
+p(String[Class])
+p(String[ Class])
+p(String [Class])
+p(String [ Class])
+p(String*Class)
+p(String* Class)
+p(String *Class)
+p(String * Class)
+class <<String
+undef :*,<<,/,[]
+end
+
+
+
+p(false::to_s)
+p(false ::to_s)
+p(false:: to_s)
+p(false :: to_s)
+
+class C2
+class <<self
+ def self.p8; p 8 end
+ alias p? p
+ alias P? p
+ alias [] p
+ alias <=> p
+end
+
+q=9
+Q=99
+
+p:p8
+false ? p: p8
+p :p8
+false ? p : p8
+
+false ? q:p8
+false ? q: p8
+false ? q :p8
+false ? q : p8
+
+#false ? Q:p8 #gives ruby indigestion
+false ? Q: p8
+#false ? Q :p8 #gives ruby indigestion
+false ? Q : p8
+
+p?:p8
+false ? p?: p8
+p? :p8
+false ? p? : p8
+
+P?:p8
+false ? P?: p8
+P? :p8
+false ? P? : p8
+
+self.[]:p8
+false ? self.[]: p8
+self.[] :p8
+false ? self.[] : p8
+
+self.<=>:p8
+false ? self.<=>: p8
+self.<=> :p8
+false ? self.<=> : p8
+
+self <=>:p8
+#false ? self <=>: p8 #gives ruby indigestion
+self <=> :p8
+#false ? self <=> : p8 #gives ruby indigestion
+end
+
+p <<stuff+'foobar'.tr('j-l','d-f')
+"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog
+stuff
+
+
+p <<p
+sdfsfdf^^^^@@@
+p
+mix=nil
+p / 5/mix
+
+module M33
+ p="var:"
+ Q="func:"
+ def Q.method_missing(name,*args)
+ self+name.to_s+(args.join' ')
+ end
+ def p.method_missing(name,*args)
+ self+name.to_s+(args.join' ')
+ end
+ def self.p(*a); super; Q end
+ @a=1
+ $a=2
+
+ p(p~6)
+ p(p ~6)
+ p(p~ 6)
+ p(p ~ 6)
+ p(p*11)
+ p(p *11)
+ p(p* 11)
+ p(p * 11)
+ p(p&proc{})
+ p(p &proc{})
+ p(p& proc{})
+ p(p & proc{})
+ p(p !1)
+# p(p ?1) #compile error, when p is var
+ p(p ! 1)
+ p(p ? 1 : 6)
+ p(p@a)
+ p(p @a)
+# p(p@ a) #wont
+# p(p @ a) #work
+ p(p#a
+)
+ p(p #a
+)
+ p(p# a
+)
+ p(p # a
+)
+ p(p$a)
+ p(p $a)
+# p(p$ a) #wont
+# p(p $ a) #work
+ p(p%Q{:foo})
+ p(p %Q{:foo})
+ p(p% Q{:foo})
+ p(p % Q{:foo})
+ p(p^6)
+ p(p ^6)
+ p(p^ 6)
+ p(p ^ 6)
+ p(p&7)
+ p(p &proc{7})
+ p(p& 7)
+ p(p & 7)
+ p(p(2))
+ p(p (2))
+ p(p( 2))
+ p(p ( 2))
+ p(p(p))
+ p(p())
+ p(p (p))
+ p(p ())
+ p(p ( p))
+ p(p ( ))
+ p(p( p))
+ p(p( ))
+ p(p)
+ p((p))
+ p(p )
+ p((p ))
+ p((p p))
+ p((p p,p))
+ p((p p))
+ p((p p,p))
+ p(p-0)
+ p(p -0)
+ p(p- 0)
+ p(p - 0)
+ p(p+9)
+ p(p +9)
+ p(p+ 9)
+ p(p + 9)
+ p(p[1])
+ p(p [1])
+ p(p[ 1])
+ p(p [ 1])
+ p(p{1})
+ p(p {1})
+ p(p{ 1})
+ p(p { 1})
+ p(p/1)
+ p(p /22)
+ p(p/ 1)
+ p(p / 22)
+ p(p._)
+ p(p ._)
+ p(p. _)
+ p(p . _)
+ p(false ? p:f)
+ p(false ? p :f)
+ p(false ? p: f)
+ p(false ? p : f)
+ p((p;1))
+ p((p ;1))
+ p((p; 1))
+ p((p ; 1))
+ p(p<1)
+ p(p <1)
+ p(p< 1)
+ p(p < 1)
+ p(p<<1)
+ p(p <<1)
+ p(p<< 1)
+ p(p << 1)
+ p(p'j')
+ p(p 'j')
+ p(p' j')
+ p(p ' j')
+ p(p"k")
+ p(p "k")
+ p(p" k")
+ p(p " k")
+ p(p|4)
+ p(p |4)
+ p(p| 4)
+ p(p | 4)
+ p(p>2)
+ p(p >2)
+ p(p> 2)
+ p(p > 2)
+
+end
+
+module M34
+ p(p~6)
+ p(p ~6)
+ p(p~ 6)
+ p(p ~ 6)
+ p(p*[1])
+ p(p *[1])
+ p(p* [1])
+ p(p * [1])
+ p(p&proc{})
+ p(p &proc{})
+ p(p& proc{})
+ p(p & proc{})
+ p(p !1)
+ p(p ?1)
+ p(p ! 1)
+ p(p ? 1 : 6)
+ p(p@a)
+ p(p @a)
+# p(p@ a) #wont
+# p(p @ a) #work
+
+ p(p#a
+)
+ p(p #a
+)
+ p(p# a
+)
+ p(p # a
+)
+ p(p$a)
+ p(p $a)
+# p(p$ a) #wont
+# p(p $ a) #work
+ p(p%Q{:foo})
+ p(p %Q{:foo})
+ p(p% Q{:foo})
+ p(p % Q{:foo})
+ p(p^6)
+ p(p ^6)
+ p(p^ 6)
+ p(p ^ 6)
+ p(p&7)
+ p(p &proc{7})
+ p(p& 7)
+ p(p & 7)
+ p(p(2))
+ p(p (2))
+ p(p( 2))
+ p(p ( 2))
+ p(p(p))
+ p(p())
+ p(p (p))
+ p(p ())
+ p(p ( p))
+ p(p ( ))
+ p(p( p))
+ p(p( ))
+ p(p)
+ p((p))
+ p(p )
+ p((p ))
+ p((p p))
+ p((p p,p))
+ p((p p))
+ p((p p,p))
+ p(p-0)
+ p(p -1)
+ p(p- 0)
+ p(p - 0)
+ p(p+9)
+ p(p +9)
+ p(p+ 9)
+ p(p + 9)
+ p(p[1])
+ p(p [1])
+ p(p[ 1])
+ p(p [ 1])
+ p(p{1})
+ p(p {1})
+ p(p{ 1})
+ p(p { 1})
+ p(p/1)
+ p(p /22/)
+ p(p/ 1)
+ p(p / 22)
+ p(p._)
+ p(p ._)
+ p(p. _)
+ p(p . _)
+ p(p:f)
+ p(p :f)
+ p(false ? p: f)
+ p(false ? p : f)
+ p((p;1))
+ p((p ;1))
+ p((p; 1))
+ p((p ; 1))
+ p(p<1)
+ p(p <1)
+ p(p< 1)
+ p(p < 1)
+ p(p<<1)
+ p(p <<1)
+foobar
+1
+ p(p<< 1)
+ p(p << 1)
+ p(p'j')
+ p(p 'j')
+ p(p' j')
+ p(p ' j')
+ p(p"k")
+ p(p "k")
+ p(p" k")
+ p(p " k")
+ p(p|4)
+ p(p |4)
+ p(p| 4)
+ p(p | 4)
+ p(p>2)
+ p(p >2)
+ p(p> 2)
+ p(p > 2)
+
+end
+
+
+def bob(x) x end
+def bill(x) x end
+p(bob %(22))
+for bob in [100] do p(bob %(22)) end
+p(bob %(22))
+def %(n) to_s+"%#{n}" end
+p(bill %(22))
+begin sdjkfsjkdfsd; rescue Object => bill; p(bill %(22)) end
+p(bill %(22))
+undef %
+
+class Object
+
+public :`
+def `(s)
+ print "bq: #{s}\n"
+end
+end
+
+69.`('what a world')
+
+79::`('what a word')
+
+p :`
+
+p{}
+p {}
+a=5
+p p +5
+p a +5
+
+def nil.+(x) ~x end
+def nil.[](*x) [x] end
+p( p + 5 )
+p( p +5 )
+p( p+5 )
+p( p[] )
+p( p [] )
+p( p [ ] )
+class NilClass; undef +,[] end
+
+class Foou
+ public
+ def [] x=-100,&y; p x; 100 end
+end
+a0=8
+p Foou.new.[]!false #value
+p Foou.new.[] !false #value
+p Foou.new.[]~9 #value
+p Foou.new.[] ~9 #value
+p Foou.new.[]-9 #op
+p Foou.new.[]+9 #op
+p Foou.new.[] -9 #value
+p Foou.new.[] +9 #value
+p Foou.new.[]<<9 #op
+p Foou.new.[] <<9 #value
+foobar
+9
+p Foou.new.[]%9 #op
+p Foou.new.[]/9 #op
+p Foou.new.[] %(9) #value
+p Foou.new.[] /9/ #value
+p Foou.new.[]$9 #value
+p Foou.new.[]a0 #value
+p Foou.new.[] $9 #value
+p Foou.new.[] a0 #value
+p Foou.new.[]{9} #lambda (op)
+p Foou.new.[] {9} #lambda (op)
+
+if p then p end
+
+p({:foo=>:bar}) #why does this work? i'd think that ':foo=' would be 1 token
+p EMPTY = 0
+p BLACK = 1
+p WHITE = - BLACK
+
+ a=b=c=0
+ a ? b:c
+ a ?b:c
+
+ p(a ? b:c)
+ p(a ?b:c)
+
+
+p~4
+p:f
+p(~4){}
+p(:f){}
+h={}
+h.default=:foo
+
+p def (h="foobar").default= v; p @v=v;v end
+p h
+
+p h.default=:b
+
+x, (*y) = [:x, :y, :z]
+p x
+p y
+
+x, *y = [:x, :y, :z]
+p x
+p y
+
+x, * = [:x, :y, :z]
+p x
+
+
+
+p Array("foo\nbar")
+
+
+
+p +(4)
+p -(4)
+
+p :'\\'
+
+class Foop
+ def Foop.bar a,b
+ p a,b
+ end
+end
+Foop.bar 1,2
+Foop::bar 3,4
+
+
+class Foop
+ def Foop::baz a,b
+ p :baz,a,b
+ end
+end
+Foop.baz 5,6
+Foop::baz 7,8
+
+
+
+without_creating=widgetname=nil
+ if without_creating && !widgetname #foo
+ fail ArgumentError,
+ "if set 'without_creating' to true, need to define 'widgetname'"
+ end
+
+
+
+=begin disable for now
+
+#class, module, and def should temporarily hide local variables
+def mopsdfjskdf arg; arg*2 end
+mopsdfjskdf=5
+ class C
+ p mopsdfjskdf %(3) #calls method
+ end
+
+module M
+ p mopsdfjskdf %(4) #calls method
+end
+
+ def d
+ p mopsdfjskdf %(5) #calls method
+ end
+p d
+p mopsdfjskdf %(6) #reads variable
+p proc{mopsdfjskdf %(7)}[] #reads variable
+
+#fancy symbols not supported yet
+p %s{symbol}
+=end
+
+#multiple assignment test
+proc {
+ a,b,c,d,e,f,g,h,i,j,k=1,2,3,4,5,6,7,8,9,10,11
+ p(b %(c))
+ p(a %(c))
+ p(k %(c))
+ p(p %(c))
+}.call
+
+
+=begin disable for now
+p "#{<<kekerz}#{"foob"
+zimpler
+kekerz
+}"
+
+
+aaa=<<whatnot; p "#{'uh,yeah'
+gonna take it down, to the nitty-grit
+gonna tell you mother-fuckers why you ain't shit
+cause suckers like you just make me strong
+whatnot
+}"
+p aaa
+
+#test variable creation in string inclusion
+#currently broken because string inclusions
+#are lexed by a separate lexer!
+proc {
+ p "jentawz: #{baz=200}"
+ p( baz %(9))
+}.call
+=end
+
+=begin ought to work...ruby doesn't like
+class A
+class B
+class C
+end
+end
+end
+def A::B::C::d() :abcd end
+def A::B::d() :abd end #this used to work as well... i think
+
+def nil.d=; end #this works
+def (;).d=; end
+def ().d=; end
+p def (p h="foobar";).default= v; p @v=v;v end
+p def (p h="foobar";h).default= v; p @v=v;v end
+
+p~4{}
+p:f{}
+p ~4{}
+p :f{}
+
+def g a=:g; [a] end
+g g g #this works
+g *g #this works
+g *g g #this doesn't
+
+[nil,p 5]
+"foo"+[1].join' '
+
+class Fook
+def foo; end
+
+
+#these work:
+(not true)
+p(!true) #etc
+(true if false) #etc
+(true and false) #etc
+(undef foo)
+(alias bar foo)
+(BEGIN{p :yyy})
+
+#these don't:
+p(not true)
+p(true if false) #etc
+p(true and false) #etc
+p(undef foo)
+p(alias bar foo)
+p(BEGIN{p :yyy})
+end
+
+=end
+
+proc {
+}
+
+p "#{<<foobar3}"
+bim
+baz
+bof
+foobar3
+
+def func
+ a,b,* = [1,2,3,4,5,6,7,8]
+ p a,b
+ a,b, = [1,2,3,4,5,6,7,8]
+ p a,b
+
+ a,b = [1,2,3,4,5,6,7,8]
+ p a,b
+ a,*b = [1,2,3,4,5,6,7,8]
+ p a,b
+
+ a,b,*c=[1,2,3,4,5,6,7,8]
+ a,b,* c=[1,2,3,4,5,6,7,8]
+end
+func
+
+
+p( %r{\/$})
+p( %r~<!include:([\/\w\.\-]+)>~m)
+
+p <<end
+#{compile_body}\
+#{outvar}
+end
+
+
+
+
+
+proc {
+ h={:a=>(foo=100)}
+ p( foo %(5))
+}.call
+
+
+p "#{<<foobar3}"
+bim
+baz
+bof
+foobar3
+
+p "#{<<foobar2
+bim
+baz
+bof
+foobar2
+}"
+
+p <<one ; p "#{<<two}"
+1111111111111111
+fdsgdfgdsfffff
+one
+2222222222222222
+sdfasdfasdfads
+two
+p "#{<<foobar0.each('|'){|s| '\nthort: '+s} }"
+jbvd|g4543ghb|!@G$dfsd|fafr|e
+|s4e5rrwware|BBBBB|*&^(*&^>"PMK:njs;d|
+
+foobar0
+
+p "#{<<foobar1.each('|'){|s| '\nthort: '+s}
+jbvd|g4543ghb|!@G$dfsd|fafr|e
+|s4e5rrwware|BBBBB|*&^(*&^>"PMK:njs;d|
+
+foobar1
+}"
+
+def foo(a=<<a,b=<<b,c=<<c)
+jfksdkjf
+dkljjkf
+a
+kdljfjkdg
+dfglkdfkgjdf
+dkf
+b
+lkdffdjksadhf
+sdflkdjgsfdkjgsdg
+dsfg;lkdflisgffd
+g
+c
+
+ a+b+c
+
+end
+p foo
+
+
+
+$a=1
+@b=2
+@@c=3
+p "#$a #@b #@@c #{$a+@b+@@c}"
+p "\#$a \#@b \#@@c \#{$a+@b+@@c}"
+p '#$a #@b #@@c #{$a+@b+@@c}'
+p '\#$a \#@b \#@@c \#{$a+@b+@@c}'
+p %w"#$a #@b #@@c #{$a+@b+@@c}"
+p %w"\#$a \#@b \#@@c \#{$a+@b+@@c}"
+p %W"#$a #@b #@@c #{$a+@b+@@c}"
+p %W"\#$a \#@b \#@@c \#{$a+@b+@@c}"
+p %Q[#$a #@b #@@c #{$a+@b+@@c}]
+p %Q[\#$a \#@b \#@@c \#{$a+@b+@@c}]
+p `echo #$a #@b #@@c #{$a+@b+@@c}`
+p `echo \#$a \#@b \#@@c \#{$a+@b+@@c}`
+p(/#$a #@b #@@c #{$a+@b+@@c}/)
+#p(/\#$a \#@b \#@@c \#{$a+@b+@@c}/) #moved to w.rb
+
+class AA; class BB; class CC
+FFOO=1
+end end end
+
+p AA::BB::CC::FFOO
+
+compile_body=outvar='foob'
+
+if false
+ method_src = c.compile(template, (HtmlCompiler::AnyData.new)).join("\n") +
+ "\n# generated by PartsTemplate::compile_partstemplate at #{Time.new}\n"
+ rescu -1
+end
+
+ p('rb_out', 'args', <<-'EOL')
+ regsub -all {!} $args {\\!} args
+ regsub -all "{" $args "\\{" args
+ if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {
+ return -code $st $ret
+ } {
+ return $ret
+ }
+ EOL
+
+def add(*args)
+ self.<<(*args)
+end
+
+
+
+val=%[13,17,22,"hike", ?\s]
+ if val.include? ?\s
+ p val.split.collect{|v| (v)}
+ end
+p "#{}"
+p "#(1)"
+class Hosts
+end
+class DNS < Hosts
+end
+def intialize(resolvers=[Hosts.new, DNS.new]) end
+def environment(env = File.basename($0, '.*')) end
+
+def ssssss &block
+end
+def params_quoted(field_name, default)
+ if block_given? then yield field_name else default end
+end
+def ==(o) 444 end
+def String.ffff4() self.to_s+"ffff" end
+
+p *[]
+for i in \
+[44,55,66,77,88] do p i**Math.sqrt(i) end
+
+#(
+for i in if
+false then foob12345; else [44,55,66,77,88] end do p i**Math.sqrt(i) end
+#)
+(
+for i in if false then
+foob12345; else [44,55,66,77,88] end do p i**Math.sqrt(i) end
+
+c=j=0
+until while j<10 do j+=1 end.nil? do p 'pppppppppp' end
+for i in if false then foob12345;
+else [44,55,66,77,88] end do p i**Math.sqrt(i) end
+
+for i in if false then foob12345; else
+[44,55,66,77,88] end do p i**Math.sqrt(i) end
+
+
+for i in (c;
+[44,55,66,77,88]) do p i**Math.sqrt(i) end
+)
+(
+
+for i in (begin
+[44,55,66,77,88] end) do p i**Math.sqrt(i) end
+
+for i in if false then foob12345; else
+[44,55,66,77,88] end do p i**Math.sqrt(i) end
+
+for i in (
+
+[44,55,66,77,88]) do p i**Math.sqrt(i) end
+
+for i in (
+[44,55,66,77,88]) do p i**Math.sqrt(i) end
+
+)
+
+
+def yy;yield end
+
+block=proc{p "blah blah"}
+
+yy &block
+p(1.+1)
+p pppp
+
+module M66
+p(proc do
+ p=123
+end.call)
+
+p proc {
+ p=123
+}.call
+
+p def pppp
+ p=123
+end
+p module Ppp
+ p=123
+end
+p class Pppp < String
+ p=123
+end
+end
+
+ def _make_regex(str) /([#{Regexp.escape(str)}])/n end
+p _make_regex("8smdf,34rh\#@\#$%$gfm/[]dD")
+
+
+p "#$a #@b #@@c
+
+d e f
+#$a #@b #@@c
+"
+
+p "\""
+
+a=a.to_s
+class <<a
+ def foobar
+ self*101
+ end
+ alias eql? ==
+end
+
+p a.foobar
+
+p(/^\s*(([+-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/)
+p(:%)
+p( { :class => class_=0})
+p cls_name = {}[:class]
+
+
+p foo
+p "#{$!.class}"
+p :p
+p(:p)
+p(:"[]")
+p :"[]"
+p("\\")
+p(/\\/)
+p(/[\\]/)
+p 0x80
+p ?p
+p 0.1
+p 0.8
+p 0.9
+p(-1)
+p %/p/
+p %Q[<LI>]
+i=99
+p %Q[<LI><A HREF="#{i[3]}.html\##{i[4]}">#{i[0]+i[1]+(i[2])}</A>\n]
+p(:side=>:top)
+p %w[a b c
+ d e f]
+p %w[a b c\n
+ d e f]
+p %w[\\]
+p %w[\]]
+p :+
+p 99 / 3
+
+a=99;b=3
+p 1+(a / b)
+p %Q[\"]
+p %Q[ some [nested] text]
+
+if false
+ formatter.format_element(element) do
+ amrita_expand_and_format1(element, context, formatter)
+ end
+end
+if false
+ ret = <<-END
+ @@parts_template = #{template.to_ruby}
+ def parts_template
+ @@parts_template
+ end
+
+ #{c.const_def_src.join("\n")}
+ def amrita_expand_and_format(element, context, formatter)
+ if element.tagname_symbol == :span and element.attrs.size == 0
+ amrita_expand_and_format1(element, context, formatter)
+ else
+ formatter.format_element(element) do
+ amrita_expand_and_format1(element, context, formatter)
+ end
+ end
+ end
+
+ def amrita_expand_and_format1(element, context, formatter)
+ #{method_src}
+ end
+ END
+ j=55
+end
+
+p '
+'
+p '\n'
+p "
+"
+p "\n"
+p %w/
+/
+p %w/\n/
+
+p %W/
+/
+p %W/\n/
+p(/
+/)
+p(/\n/)
+p proc {
+ p `
+ `
+ p `\n`
+}
+
+
+
+p(%r[foo]i)
+#breakpoint
+p <<stuff+'foobar'.tr('j-l','d-f')
+"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog
+stuff
+
+=begin doesn't work
+p <<stuff+'foobar'.tr('j-l','d-f')\
++"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog
+stuff
+=end
+
+p ENV["AmritaCacheDir"]
+p <<-BEGIN + <<-END
+ def element_downcase(attributes = {})
+ BEGIN
+ end
+ END
+
+
+
+p <<ggg; def
+kleegarts() p 'kkkkkkk' end
+dfgdgfdf
+ggg
+koomblatz!() p 'jdkfsk' end
+
+koomblatz!
+
+p f = 3.7517675036461267e+17
+p $10
+p $1001
+p( <<end )
+nine time nine men have stood untold.
+end
+
+def jd_to_wday(jd) (jd + 1) % 7 end
+p jd_to_wday(98)
+
+
+p pre = $`
+=begin
+=end
+
+p <<"..end .."
+cbkvjb
+vb;lkxcvkbxc
+vxlc;kblxckvb
+xcvblcvb
+..end ..
+
+p $-j=55
+
+def empty() end
+
+p <<a
+dkflg
+flk
+a
+
+label='label';tab=[1,2,3]
+ p <<S
+#{label} = arr = Array.new(#{tab.size}, nil)
+str = a = i = nil
+idx = 0
+clist.each do |str|
+ str.split(',', -1).each do |i|
+ arr[idx] = i.to_i unless i.empty?
+ idx += 1
+ end
+end
+
+S
+def printem1 a,b,c
+ p(a +77)
+ p(b +77)
+ p(c +77)
+end
+
+def foobar() end
+def foobar2
+end
+
+def printem0(a)
+ p(a +77)
+end
+def printem0(a,b,c)
+ p(a +77)
+ p(b +77)
+ p(c +77)
+end
+def printem2 a,b,c; p(a +77); p(b +77); p(c +77) end
+def three() (1+2) end
+
+def d;end
+def d()end
+def d(dd)end
+
+def printem a,b,c
+ p a;p b;p c
+ p(a +77)
+ p(b %(0.123))
+end
+printem 1,2,3
+
+a=1
+p(a +77)
+
+def hhh(a=(1+2)) a end
+
+
+
+END {
+ p "bye-bye"
+}
+
+
+p <<here
+where?
+here
+p <<-what
+ ? that's
+ what
+p proc{||}
+for i in if false
+foob12345; else [44,55,66,77,88] end do p i**Math.sqrt(i) end
+p "\v"
+c=0
+ while c == /[ \t\f\r\13]/; end
+
+
+
+
+
+
+
+
diff --git a/test/ruby/evil.out.raydebug b/test/ruby/evil.out.raydebug new file mode 100644 index 0000000..2dd4b7b --- /dev/null +++ b/test/ruby/evil.out.raydebug @@ -0,0 +1,1123 @@ +ident(p)operator(()constant(String) operator(*)constant(Class)operator(\))
+reserved(class) class(String)
+reserved(class) class(Class)
+reserved(end)
+reserved(end)
+comment(#def String(x\) x.to_s end #it's already built-in. duh!)
+reserved(def) constant(String)operator(.)operator(*)operator(()ident(right)operator(\)) operator([)pre_constant(self)operator(,)ident(right)operator(]) reserved(end)
+reserved(def) constant(String)operator(.)operator(<<)operator(()ident(right)operator(\)) operator([)pre_constant(self)operator(,)symbol(:<<)operator(,)ident(right)operator(]) reserved(end)
+reserved(def) constant(String)operator(.)operator(/)operator(()ident(right)operator(\)) operator([)pre_constant(self)operator(,)symbol(:/)operator(,)ident(right)operator(]) reserved(end)
+reserved(def) constant(String)operator(.)operator([])operator(()ident(right)operator(\)) operator([)pre_constant(self)operator(,)symbol(:[])operator(,)ident(right)operator(]) reserved(end)
+ident(p)operator(()constant(String)operator(::)constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(::) constant(Class)operator(\))
+ident(p)operator(()constant(String) operator(::)constant(Class)operator(\))
+ident(p)operator(()constant(String) operator(::) constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(<<)constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(<<) constant(Class)operator(\))
+ident(p)operator(()constant(String) string<delimiter(<<Class)>operator(\)) string<content(
+sgsdfgf)delimiter(
+Class)>
+ident(p)operator(()constant(String) operator(<<) constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(/)constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(/) constant(Class)operator(\))
+ident(p)operator(()constant(String) regexp<delimiter(/)content(Class)delimiter(/)>operator(\))
+ident(p)operator(()constant(String) operator(/) constant(Class)operator(\)) comment(#borken)
+ident(p)operator(()constant(String)operator([)constant(Class)operator(])operator(\))
+ident(p)operator(()constant(String)operator([) constant(Class)operator(])operator(\))
+ident(p)operator(()constant(String) operator([)constant(Class)operator(])operator(\))
+ident(p)operator(()constant(String) operator([) constant(Class)operator(])operator(\))
+ident(p)operator(()constant(String)operator(*)constant(Class)operator(\))
+ident(p)operator(()constant(String)operator(*) constant(Class)operator(\))
+ident(p)operator(()constant(String) operator(*)constant(Class)operator(\))
+ident(p)operator(()constant(String) operator(*) constant(Class)operator(\))
+reserved(class) operator(<<)class(String)
+reserved(undef) symbol(:*)operator(,)method(<<)operator(,)method(/)operator(,)method([])
+reserved(end)
+
+
+
+ident(p)operator(()pre_constant(false)operator(::)ident(to_s)operator(\))
+ident(p)operator(()pre_constant(false) operator(::)ident(to_s)operator(\))
+ident(p)operator(()pre_constant(false)operator(::) ident(to_s)operator(\))
+ident(p)operator(()pre_constant(false) operator(::) ident(to_s)operator(\))
+
+reserved(class) class(C2)
+reserved(class) operator(<<)class(self)
+ reserved(def) pre_constant(self)operator(.)ident(p8)operator(;) ident(p) integer(8) reserved(end)
+ reserved(alias) ident(p?) ident(p)
+ reserved(alias) ident(P?) ident(p)
+ reserved(alias) operator([)operator(]) ident(p)
+ reserved(alias) operator(<=>) ident(p)
+reserved(end)
+
+ident(q)operator(=)integer(9)
+constant(Q)operator(=)integer(99)
+
+ident(p)symbol(:p8)
+pre_constant(false) operator(?) ident(p)operator(:) ident(p8)
+ident(p) symbol(:p8)
+pre_constant(false) operator(?) ident(p) operator(:) ident(p8)
+
+pre_constant(false) operator(?) ident(q)symbol(:p8)
+pre_constant(false) operator(?) ident(q)operator(:) ident(p8)
+pre_constant(false) operator(?) ident(q) symbol(:p8)
+pre_constant(false) operator(?) ident(q) operator(:) ident(p8)
+
+comment(#false ? Q:p8 #gives ruby indigestion)
+pre_constant(false) operator(?) constant(Q)operator(:) ident(p8)
+comment(#false ? Q :p8 #gives ruby indigestion)
+pre_constant(false) operator(?) constant(Q) operator(:) ident(p8)
+
+ident(p?)symbol(:p8)
+pre_constant(false) operator(?) ident(p?)operator(:) ident(p8)
+ident(p?) symbol(:p8)
+pre_constant(false) operator(?) ident(p?) operator(:) ident(p8)
+
+ident(P?)symbol(:p8)
+pre_constant(false) operator(?) ident(P?)operator(:) ident(p8)
+ident(P?) symbol(:p8)
+pre_constant(false) operator(?) ident(P?) operator(:) ident(p8)
+
+pre_constant(self)operator(.)operator([])symbol(:p8)
+pre_constant(false) operator(?) pre_constant(self)operator(.)operator([])operator(:) ident(p8)
+pre_constant(self)operator(.)operator([]) symbol(:p8)
+pre_constant(false) operator(?) pre_constant(self)operator(.)operator([]) operator(:) ident(p8)
+
+pre_constant(self)operator(.)operator(<=>)symbol(:p8)
+pre_constant(false) operator(?) pre_constant(self)operator(.)operator(<=>)operator(:) ident(p8)
+pre_constant(self)operator(.)operator(<=>) symbol(:p8)
+pre_constant(false) operator(?) pre_constant(self)operator(.)operator(<=>) operator(:) ident(p8)
+
+pre_constant(self) operator(<=>)symbol(:p8)
+comment(#false ? self <=>: p8 #gives ruby indigestion)
+pre_constant(self) operator(<=>) symbol(:p8)
+comment(#false ? self <=> : p8 #gives ruby indigestion)
+reserved(end)
+
+ident(p) string<delimiter(<<stuff)>operator(+)string<delimiter(')content(foobar)delimiter(')>operator(.)ident(tr)operator(()string<delimiter(')content(j-l)delimiter(')>operator(,)string<delimiter(')content(d-f)delimiter(')>operator(\))string<content(
+"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog)delimiter(
+stuff)>
+
+
+ident(p) string<delimiter(<<p)>string<content(
+sdfsfdf^^^^@@@)delimiter(
+p)>
+ident(mix)operator(=)pre_constant(nil)
+ident(p) operator(/) integer(5)operator(/)ident(mix)
+
+reserved(module) class(M33)
+ ident(p)operator(=)string<delimiter(")content(var:)delimiter(")>
+ constant(Q)operator(=)string<delimiter(")content(func:)delimiter(")>
+ reserved(def) constant(Q)operator(.)ident(method_missing)operator(()ident(name)operator(,)operator(*)ident(args)operator(\))
+ pre_constant(self)operator(+)ident(name)operator(.)ident(to_s)operator(+)operator(()ident(args)operator(.)ident(join)string<delimiter(')content( )delimiter(')>operator(\))
+ reserved(end)
+ reserved(def) ident(p)operator(.)ident(method_missing)operator(()ident(name)operator(,)operator(*)ident(args)operator(\))
+ pre_constant(self)operator(+)ident(name)operator(.)ident(to_s)operator(+)operator(()ident(args)operator(.)ident(join)string<delimiter(')content( )delimiter(')>operator(\))
+ reserved(end)
+ reserved(def) pre_constant(self)operator(.)ident(p)operator(()operator(*)ident(a)operator(\))operator(;) reserved(super)operator(;) constant(Q) reserved(end)
+ instance_variable(@a)operator(=)integer(1)
+ global_variable($a)operator(=)integer(2)
+
+ ident(p)operator(()ident(p)operator(~)integer(6)operator(\))
+ ident(p)operator(()ident(p) operator(~)integer(6)operator(\))
+ ident(p)operator(()ident(p)operator(~) integer(6)operator(\))
+ ident(p)operator(()ident(p) operator(~) integer(6)operator(\))
+ ident(p)operator(()ident(p)operator(*)integer(11)operator(\))
+ ident(p)operator(()ident(p) operator(*)integer(11)operator(\))
+ ident(p)operator(()ident(p)operator(*) integer(11)operator(\))
+ ident(p)operator(()ident(p) operator(*) integer(11)operator(\))
+ ident(p)operator(()ident(p)operator(&)ident(proc)operator({)operator(})operator(\))
+ ident(p)operator(()ident(p) operator(&)ident(proc)operator({)operator(})operator(\))
+ ident(p)operator(()ident(p)operator(&) ident(proc)operator({)operator(})operator(\))
+ ident(p)operator(()ident(p) operator(&) ident(proc)operator({)operator(})operator(\))
+ ident(p)operator(()ident(p) operator(!)integer(1)operator(\))
+comment(# p(p ?1\) #compile error, when p is var)
+ ident(p)operator(()ident(p) operator(!) integer(1)operator(\))
+ ident(p)operator(()ident(p) operator(?) integer(1) operator(:) integer(6)operator(\))
+ ident(p)operator(()ident(p)instance_variable(@a)operator(\))
+ ident(p)operator(()ident(p) instance_variable(@a)operator(\))
+comment(# p(p@ a\) #wont)
+comment(# p(p @ a\) #work )
+ ident(p)operator(()ident(p)comment(#a)
+operator(\))
+ ident(p)operator(()ident(p) comment(#a)
+operator(\))
+ ident(p)operator(()ident(p)comment(# a)
+operator(\))
+ ident(p)operator(()ident(p) comment(# a)
+operator(\))
+ ident(p)operator(()ident(p)global_variable($a)operator(\))
+ ident(p)operator(()ident(p) global_variable($a)operator(\))
+comment(# p(p$ a\) #wont)
+comment(# p(p $ a\) #work)
+ ident(p)operator(()ident(p)operator(%)constant(Q)operator({)symbol(:foo)operator(})operator(\))
+ ident(p)operator(()ident(p) string<delimiter(%Q{)content(:foo)delimiter(})>operator(\))
+ ident(p)operator(()ident(p)operator(%) constant(Q)operator({)symbol(:foo)operator(})operator(\))
+ ident(p)operator(()ident(p) operator(%) constant(Q)operator({)symbol(:foo)operator(})operator(\))
+ ident(p)operator(()ident(p)operator(^)integer(6)operator(\))
+ ident(p)operator(()ident(p) operator(^)integer(6)operator(\))
+ ident(p)operator(()ident(p)operator(^) integer(6)operator(\))
+ ident(p)operator(()ident(p) operator(^) integer(6)operator(\))
+ ident(p)operator(()ident(p)operator(&)integer(7)operator(\))
+ ident(p)operator(()ident(p) operator(&)ident(proc)operator({)integer(7)operator(})operator(\))
+ ident(p)operator(()ident(p)operator(&) integer(7)operator(\))
+ ident(p)operator(()ident(p) operator(&) integer(7)operator(\))
+ ident(p)operator(()ident(p)operator(()integer(2)operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(()integer(2)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(() integer(2)operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(() integer(2)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(()ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(()operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(()ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(()operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(() ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(() operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(() ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(() operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(\))
+ ident(p)operator(()operator(()ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p) operator(\))
+ ident(p)operator(()operator(()ident(p) operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) ident(p)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) ident(p)operator(,)ident(p)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) ident(p)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) ident(p)operator(,)ident(p)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(-)integer(0)operator(\))
+ ident(p)operator(()ident(p) operator(-)integer(0)operator(\))
+ ident(p)operator(()ident(p)operator(-) integer(0)operator(\))
+ ident(p)operator(()ident(p) operator(-) integer(0)operator(\))
+ ident(p)operator(()ident(p)operator(+)integer(9)operator(\))
+ ident(p)operator(()ident(p) operator(+)integer(9)operator(\))
+ ident(p)operator(()ident(p)operator(+) integer(9)operator(\))
+ ident(p)operator(()ident(p) operator(+) integer(9)operator(\))
+ ident(p)operator(()ident(p)operator([)integer(1)operator(])operator(\))
+ ident(p)operator(()ident(p) operator([)integer(1)operator(])operator(\))
+ ident(p)operator(()ident(p)operator([) integer(1)operator(])operator(\))
+ ident(p)operator(()ident(p) operator([) integer(1)operator(])operator(\))
+ ident(p)operator(()ident(p)operator({)integer(1)operator(})operator(\))
+ ident(p)operator(()ident(p) operator({)integer(1)operator(})operator(\))
+ ident(p)operator(()ident(p)operator({) integer(1)operator(})operator(\))
+ ident(p)operator(()ident(p) operator({) integer(1)operator(})operator(\))
+ ident(p)operator(()ident(p)operator(/)integer(1)operator(\))
+ ident(p)operator(()ident(p) regexp<delimiter(/)content(22\)
+ p(p)delimiter(/)> integer(1)operator(\))
+ ident(p)operator(()ident(p) operator(/) integer(22)operator(\))
+ ident(p)operator(()ident(p)operator(.)ident(_)operator(\))
+ ident(p)operator(()ident(p) operator(.)ident(_)operator(\))
+ ident(p)operator(()ident(p)operator(.) ident(_)operator(\))
+ ident(p)operator(()ident(p) operator(.) ident(_)operator(\))
+ ident(p)operator(()pre_constant(false) operator(?) ident(p)symbol(:f)operator(\))
+ ident(p)operator(()pre_constant(false) operator(?) ident(p) symbol(:f)operator(\))
+ ident(p)operator(()pre_constant(false) operator(?) ident(p)operator(:) ident(f)operator(\))
+ ident(p)operator(()pre_constant(false) operator(?) ident(p) operator(:) ident(f)operator(\))
+ ident(p)operator(()operator(()ident(p)operator(;)integer(1)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) operator(;)integer(1)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p)operator(;) integer(1)operator(\))operator(\))
+ ident(p)operator(()operator(()ident(p) operator(;) integer(1)operator(\))operator(\))
+ ident(p)operator(()ident(p)operator(<)integer(1)operator(\))
+ ident(p)operator(()ident(p) operator(<)integer(1)operator(\))
+ ident(p)operator(()ident(p)operator(<) integer(1)operator(\))
+ ident(p)operator(()ident(p) operator(<) integer(1)operator(\))
+ ident(p)operator(()ident(p)operator(<<)integer(1)operator(\))
+ ident(p)operator(()ident(p) string<delimiter(<<1)>operator(\))string<content(
+ p(p<< 1\)
+ p(p << 1\)
+ p(p'j'\)
+ p(p 'j'\)
+ p(p' j'\)
+ p(p ' j'\)
+ p(p"k"\)
+ p(p "k"\)
+ p(p" k"\)
+ p(p " k"\)
+ p(p|4\)
+ p(p |4\)
+ p(p| 4\)
+ p(p | 4\)
+ p(p>2\)
+ p(p >2\)
+ p(p> 2\)
+ p(p > 2\)
+
+end
+
+module M34
+ p(p~6\)
+ p(p ~6\)
+ p(p~ 6\)
+ p(p ~ 6\)
+ p(p*[1]\)
+ p(p *[1]\)
+ p(p* [1]\)
+ p(p * [1]\)
+ p(p&proc{}\)
+ p(p &proc{}\)
+ p(p& proc{}\)
+ p(p & proc{}\)
+ p(p !1\)
+ p(p ?1\)
+ p(p ! 1\)
+ p(p ? 1 : 6\)
+ p(p@a\)
+ p(p @a\)
+# p(p@ a\) #wont
+# p(p @ a\) #work
+
+ p(p#a
+\)
+ p(p #a
+\)
+ p(p# a
+\)
+ p(p # a
+\)
+ p(p$a\)
+ p(p $a\)
+# p(p$ a\) #wont
+# p(p $ a\) #work
+ p(p%Q{:foo}\)
+ p(p %Q{:foo}\)
+ p(p% Q{:foo}\)
+ p(p % Q{:foo}\)
+ p(p^6\)
+ p(p ^6\)
+ p(p^ 6\)
+ p(p ^ 6\)
+ p(p&7\)
+ p(p &proc{7}\)
+ p(p& 7\)
+ p(p & 7\)
+ p(p(2\)\)
+ p(p (2\)\)
+ p(p( 2\)\)
+ p(p ( 2\)\)
+ p(p(p\)\)
+ p(p(\)\)
+ p(p (p\)\)
+ p(p (\)\)
+ p(p ( p\)\)
+ p(p ( \)\)
+ p(p( p\)\)
+ p(p( \)\)
+ p(p\)
+ p((p\)\)
+ p(p \)
+ p((p \)\)
+ p((p p\)\)
+ p((p p,p\)\)
+ p((p p\)\)
+ p((p p,p\)\)
+ p(p-0\)
+ p(p -1\)
+ p(p- 0\)
+ p(p - 0\)
+ p(p+9\)
+ p(p +9\)
+ p(p+ 9\)
+ p(p + 9\)
+ p(p[1]\)
+ p(p [1]\)
+ p(p[ 1]\)
+ p(p [ 1]\)
+ p(p{1}\)
+ p(p {1}\)
+ p(p{ 1}\)
+ p(p { 1}\)
+ p(p/1\)
+ p(p /22/\)
+ p(p/ 1\)
+ p(p / 22\)
+ p(p._\)
+ p(p ._\)
+ p(p. _\)
+ p(p . _\)
+ p(p:f\)
+ p(p :f\)
+ p(false ? p: f\)
+ p(false ? p : f\)
+ p((p;1\)\)
+ p((p ;1\)\)
+ p((p; 1\)\)
+ p((p ; 1\)\)
+ p(p<1\)
+ p(p <1\)
+ p(p< 1\)
+ p(p < 1\)
+ p(p<<1\)
+ p(p <<1\)
+foobar)delimiter(
+1)>
+ ident(p)operator(()ident(p)operator(<<) integer(1)operator(\))
+ ident(p)operator(()ident(p) operator(<<) integer(1)operator(\))
+ ident(p)operator(()ident(p)string<delimiter(')content(j)delimiter(')>operator(\))
+ ident(p)operator(()ident(p) string<delimiter(')content(j)delimiter(')>operator(\))
+ ident(p)operator(()ident(p)string<delimiter(')content( j)delimiter(')>operator(\))
+ ident(p)operator(()ident(p) string<delimiter(')content( j)delimiter(')>operator(\))
+ ident(p)operator(()ident(p)string<delimiter(")content(k)delimiter(")>operator(\))
+ ident(p)operator(()ident(p) string<delimiter(")content(k)delimiter(")>operator(\))
+ ident(p)operator(()ident(p)string<delimiter(")content( k)delimiter(")>operator(\))
+ ident(p)operator(()ident(p) string<delimiter(")content( k)delimiter(")>operator(\))
+ ident(p)operator(()ident(p)operator(|)integer(4)operator(\))
+ ident(p)operator(()ident(p) operator(|)integer(4)operator(\))
+ ident(p)operator(()ident(p)operator(|) integer(4)operator(\))
+ ident(p)operator(()ident(p) operator(|) integer(4)operator(\))
+ ident(p)operator(()ident(p)operator(>)integer(2)operator(\))
+ ident(p)operator(()ident(p) operator(>)integer(2)operator(\))
+ ident(p)operator(()ident(p)operator(>) integer(2)operator(\))
+ ident(p)operator(()ident(p) operator(>) integer(2)operator(\))
+
+reserved(end)
+
+
+reserved(def) method(bob)operator(()ident(x)operator(\)) ident(x) reserved(end)
+reserved(def) method(bill)operator(()ident(x)operator(\)) ident(x) reserved(end)
+ident(p)operator(()ident(bob) string<delimiter(%()content(22)delimiter(\))>operator(\))
+reserved(for) ident(bob) reserved(in) operator([)integer(100)operator(]) reserved(do) ident(p)operator(()ident(bob) string<delimiter(%()content(22)delimiter(\))>operator(\)) reserved(end)
+ident(p)operator(()ident(bob) string<delimiter(%()content(22)delimiter(\))>operator(\))
+reserved(def) method(%)operator(()ident(n)operator(\)) ident(to_s)operator(+)string<delimiter(")content(%)inline<delimiter(#{)ident(n)delimiter(})>delimiter(")> reserved(end)
+ident(p)operator(()ident(bill) string<delimiter(%()content(22)delimiter(\))>operator(\))
+reserved(begin) ident(sdjkfsjkdfsd)operator(;) reserved(rescue) constant(Object) operator(=)operator(>) ident(bill)operator(;) ident(p)operator(()ident(bill) string<delimiter(%()content(22)delimiter(\))>operator(\)) reserved(end)
+ident(p)operator(()ident(bill) string<delimiter(%()content(22)delimiter(\))>operator(\))
+reserved(undef) method(%)
+
+reserved(class) class(Object)
+
+ident(public) symbol(:`)
+reserved(def) method(`)operator(()ident(s)operator(\))
+ ident(print) string<delimiter(")content(bq: )inline<delimiter(#{)ident(s)delimiter(})>char(\\n)delimiter(")>
+reserved(end)
+reserved(end)
+
+integer(69)operator(.)operator(`)operator(()string<delimiter(')content(what a world)delimiter(')>operator(\))
+
+integer(79)operator(::)operator(`)operator(()string<delimiter(')content(what a word)delimiter(')>operator(\))
+
+ident(p) symbol(:`)
+
+ident(p)operator({)operator(})
+ident(p) operator({)operator(})
+ident(a)operator(=)integer(5)
+ident(p) ident(p) operator(+)integer(5)
+ident(p) ident(a) operator(+)integer(5)
+
+reserved(def) pre_constant(nil)operator(.)operator(+)operator(()ident(x)operator(\)) operator(~)ident(x) reserved(end)
+reserved(def) pre_constant(nil)operator(.)operator([])operator(()operator(*)ident(x)operator(\)) operator([)ident(x)operator(]) reserved(end)
+ident(p)operator(() ident(p) operator(+) integer(5) operator(\))
+ident(p)operator(() ident(p) operator(+)integer(5) operator(\))
+ident(p)operator(() ident(p)operator(+)integer(5) operator(\))
+ident(p)operator(() ident(p)operator([)operator(]) operator(\))
+ident(p)operator(() ident(p) operator([)operator(]) operator(\))
+ident(p)operator(() ident(p) operator([) operator(]) operator(\))
+reserved(class) class(NilClass)operator(;) reserved(undef) method(+)operator(,)method([]) reserved(end)
+
+reserved(class) class(Foou)
+ ident(public)
+ reserved(def) method([]) ident(x)operator(=)operator(-)integer(100)operator(,)operator(&)ident(y)operator(;) ident(p) ident(x)operator(;) integer(100) reserved(end)
+reserved(end)
+ident(a0)operator(=)integer(8)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(!)pre_constant(false) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator(!)pre_constant(false) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(~)integer(9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator(~)integer(9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(-)integer(9) comment(#op)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(+)integer(9) comment(#op)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator(-)integer(9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator(+)integer(9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(<<)integer(9) comment(#op)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) string<delimiter(<<9)> comment(#value)string<content(
+foobar)delimiter(
+9)>
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(%)integer(9) comment(#op)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator(/)integer(9) comment(#op)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) string<delimiter(%()content(9)delimiter(\))> comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator(/)integer(9)operator(/) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])global_variable($9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])ident(a0) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) global_variable($9) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) ident(a0) comment(#value)
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([])operator({)integer(9)operator(}) comment(#lambda (op\))
+ident(p) constant(Foou)operator(.)ident(new)operator(.)operator([]) operator({)integer(9)operator(}) comment(#lambda (op\))
+
+reserved(if) ident(p) reserved(then) ident(p) reserved(end)
+
+ident(p)operator(()operator({)symbol(:foo=)operator(>)symbol(:bar)operator(})operator(\)) comment(#why does this work? i'd think that ':foo=' would be 1 token)
+ident(p) constant(EMPTY) operator(=) integer(0)
+ident(p) constant(BLACK) operator(=) integer(1)
+ident(p) constant(WHITE) operator(=) operator(-) constant(BLACK)
+
+ ident(a)operator(=)ident(b)operator(=)ident(c)operator(=)integer(0)
+ ident(a) operator(?) ident(b)symbol(:c)
+ ident(a) integer(?b)symbol(:c)
+
+ ident(p)operator(()ident(a) operator(?) ident(b)symbol(:c)operator(\))
+ ident(p)operator(()ident(a) integer(?b)symbol(:c)operator(\))
+
+
+ident(p)operator(~)integer(4)
+ident(p)symbol(:f)
+ident(p)operator(()operator(~)integer(4)operator(\))operator({)operator(})
+ident(p)operator(()symbol(:f)operator(\))operator({)operator(})
+ident(h)operator(=)operator({)operator(})
+ident(h)operator(.)ident(default)operator(=)symbol(:foo)
+
+ident(p) reserved(def) operator(()ident(h)operator(=)string<delimiter(")content(foobar)delimiter(")>operator(\))operator(.)ident(default)operator(=) ident(v)operator(;) ident(p) instance_variable(@v)operator(=)ident(v)operator(;)ident(v) reserved(end)
+ident(p) ident(h)
+
+ident(p) ident(h)operator(.)ident(default)operator(=)symbol(:b)
+
+ident(x)operator(,) operator(()operator(*)ident(y)operator(\)) operator(=) operator([)symbol(:x)operator(,) symbol(:y)operator(,) symbol(:z)operator(])
+ident(p) ident(x)
+ident(p) ident(y)
+
+ident(x)operator(,) operator(*)ident(y) operator(=) operator([)symbol(:x)operator(,) symbol(:y)operator(,) symbol(:z)operator(])
+ident(p) ident(x)
+ident(p) ident(y)
+
+ident(x)operator(,) operator(*) operator(=) operator([)symbol(:x)operator(,) symbol(:y)operator(,) symbol(:z)operator(])
+ident(p) ident(x)
+
+
+
+ident(p) constant(Array)operator(()string<delimiter(")content(foo)char(\\n)content(bar)delimiter(")>operator(\))
+
+
+
+ident(p) operator(+)operator(()integer(4)operator(\))
+ident(p) operator(-)operator(()integer(4)operator(\))
+
+ident(p) symbol<symbol(:)delimiter(')char(\\\\)delimiter(')>
+
+reserved(class) class(Foop)
+ reserved(def) constant(Foop)operator(.)ident(bar) ident(a)operator(,)ident(b)
+ ident(p) ident(a)operator(,)ident(b)
+ reserved(end)
+reserved(end)
+constant(Foop)operator(.)ident(bar) integer(1)operator(,)integer(2)
+constant(Foop)operator(::)ident(bar) integer(3)operator(,)integer(4)
+
+
+reserved(class) class(Foop)
+ reserved(def) constant(Foop)operator(::)ident(baz) ident(a)operator(,)ident(b)
+ ident(p) symbol(:baz)operator(,)ident(a)operator(,)ident(b)
+ reserved(end)
+reserved(end)
+constant(Foop)operator(.)ident(baz) integer(5)operator(,)integer(6)
+constant(Foop)operator(::)ident(baz) integer(7)operator(,)integer(8)
+
+
+
+ident(without_creating)operator(=)ident(widgetname)operator(=)pre_constant(nil)
+ reserved(if) ident(without_creating) operator(&&) operator(!)ident(widgetname) comment(#foo)
+ ident(fail) constant(ArgumentError)operator(,)
+ string<delimiter(")content(if set 'without_creating' to true, need to define 'widgetname')delimiter(")>
+ reserved(end)
+
+
+
+comment(=begin disable for now
+
+#class, module, and def should temporarily hide local variables
+def mopsdfjskdf arg; arg*2 end
+mopsdfjskdf=5
+ class C
+ p mopsdfjskdf %(3\) #calls method
+ end
+
+module M
+ p mopsdfjskdf %(4\) #calls method
+end
+
+ def d
+ p mopsdfjskdf %(5\) #calls method
+ end
+p d
+p mopsdfjskdf %(6\) #reads variable
+p proc{mopsdfjskdf %(7\)}[] #reads variable
+
+#fancy symbols not supported yet
+p %s{symbol}
+=end)
+
+comment(#multiple assignment test)
+ident(proc) operator({)
+ ident(a)operator(,)ident(b)operator(,)ident(c)operator(,)ident(d)operator(,)ident(e)operator(,)ident(f)operator(,)ident(g)operator(,)ident(h)operator(,)ident(i)operator(,)ident(j)operator(,)ident(k)operator(=)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(,)integer(9)operator(,)integer(10)operator(,)integer(11)
+ ident(p)operator(()ident(b) string<delimiter(%()content(c)delimiter(\))>operator(\))
+ ident(p)operator(()ident(a) string<delimiter(%()content(c)delimiter(\))>operator(\))
+ ident(p)operator(()ident(k) string<delimiter(%()content(c)delimiter(\))>operator(\))
+ ident(p)operator(()ident(p) string<delimiter(%()content(c)delimiter(\))>operator(\))
+operator(})operator(.)ident(call)
+
+
+comment(=begin disable for now
+p "#{<<kekerz}#{"foob"
+zimpler
+kekerz
+}"
+
+
+aaa=<<whatnot; p "#{'uh,yeah'
+gonna take it down, to the nitty-grit
+gonna tell you mother-fuckers why you ain't shit
+cause suckers like you just make me strong
+whatnot
+}"
+p aaa
+
+#test variable creation in string inclusion
+#currently broken because string inclusions
+#are lexed by a separate lexer!
+proc {
+ p "jentawz: #{baz=200}"
+ p( baz %(9\)\)
+}.call
+=end)
+
+comment(=begin ought to work...ruby doesn't like
+class A
+class B
+class C
+end
+end
+end
+def A::B::C::d(\) :abcd end
+def A::B::d(\) :abd end #this used to work as well... i think
+
+def nil.d=; end #this works
+def (;\).d=; end
+def (\).d=; end
+p def (p h="foobar";\).default= v; p @v=v;v end
+p def (p h="foobar";h\).default= v; p @v=v;v end
+
+p~4{}
+p:f{}
+p ~4{}
+p :f{}
+
+def g a=:g; [a] end
+g g g #this works
+g *g #this works
+g *g g #this doesn't
+
+[nil,p 5]
+"foo"+[1].join' '
+
+class Fook
+def foo; end
+
+
+#these work:
+(not true\)
+p(!true\) #etc
+(true if false\) #etc
+(true and false\) #etc
+(undef foo\)
+(alias bar foo\)
+(BEGIN{p :yyy}\)
+
+#these don't:
+p(not true\)
+p(true if false\) #etc
+p(true and false\) #etc
+p(undef foo\)
+p(alias bar foo\)
+p(BEGIN{p :yyy}\)
+end
+
+=end)
+
+ident(proc) operator({)
+operator(})
+
+ident(p) string<delimiter(")inline<delimiter(#{)string<delimiter(<<foobar3)>delimiter(})>delimiter(")>
+ident(bim)
+ident(baz)
+ident(bof)
+ident(foobar3)
+
+reserved(def) method(func)
+ ident(a)operator(,)ident(b)operator(,)operator(*) operator(=) operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+ ident(p) ident(a)operator(,)ident(b)
+ ident(a)operator(,)ident(b)operator(,) operator(=) operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+ ident(p) ident(a)operator(,)ident(b)
+
+ ident(a)operator(,)ident(b) operator(=) operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+ ident(p) ident(a)operator(,)ident(b)
+ ident(a)operator(,)operator(*)ident(b) operator(=) operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+ ident(p) ident(a)operator(,)ident(b)
+
+ ident(a)operator(,)ident(b)operator(,)operator(*)ident(c)operator(=)operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+ ident(a)operator(,)ident(b)operator(,)operator(*) ident(c)operator(=)operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(,)integer(4)operator(,)integer(5)operator(,)integer(6)operator(,)integer(7)operator(,)integer(8)operator(])
+reserved(end)
+ident(func)
+
+
+ident(p)operator(() regexp<delimiter(%r{)char(\\/)content($)delimiter(})>operator(\))
+ident(p)operator(() regexp<delimiter(%r~)content(<!include:([)char(\\/)char(\\w)char(\\.)char(\\-)content(]+\)>)delimiter(~)modifier(m)>operator(\))
+
+ident(p) string<delimiter(<<end)>string<content(
+)inline<delimiter(#{)ident(compile_body)delimiter(})>char(\\
+)inline<delimiter(#{)ident(outvar)delimiter(})>delimiter(
+end)>
+
+
+
+
+
+ident(proc) operator({)
+ ident(h)operator(=)operator({)symbol(:a=)operator(>)operator(()ident(foo)operator(=)integer(100)operator(\))operator(})
+ ident(p)operator(() ident(foo) string<delimiter(%()content(5)delimiter(\))>operator(\))
+operator(})operator(.)ident(call)
+
+
+ident(p) string<delimiter(")inline<delimiter(#{)string<delimiter(<<foobar3)>delimiter(})>delimiter(")>
+ident(bim)
+ident(baz)
+ident(bof)
+ident(foobar3)
+
+ident(p) string<delimiter(")inline<delimiter(#{)string<delimiter(<<foobar2)>string<content(
+bim
+baz
+bof)delimiter(
+foobar2)>
+delimiter(})>delimiter(")>
+
+ident(p) string<delimiter(<<one)> operator(;) ident(p) string<delimiter(")inline<delimiter(#{)string<delimiter(<<two)>delimiter(})>delimiter(")>string<content(
+1111111111111111
+fdsgdfgdsfffff)delimiter(
+one)>string<content(
+2222222222222222
+sdfasdfasdfads)delimiter(
+two)>
+ident(p) string<delimiter(")inline<delimiter(#{)string<delimiter(<<foobar0)>operator(.)ident(each)operator(()string<delimiter(')content(|)delimiter(')>operator(\))operator({)operator(|)ident(s)operator(|) string<delimiter(')content(\\n)content(thort: )delimiter(')>operator(+)ident(s)operator(}) delimiter(})>delimiter(")>
+ident(jbvd)operator(|)ident(g4543ghb)operator(|)operator(!)instance_variable(@G)global_variable($dfsd)operator(|)ident(fafr)operator(|)ident(e)
+operator(|)ident(s4e5rrwware)operator(|)constant(BBBBB)operator(|*)operator(&)operator(^)operator(()operator(*&)operator(^)operator(>)string<delimiter(")content(PMK:njs;d|
+
+foobar0
+
+p )delimiter(")>comment(#{<<foobar1.each('|'\){|s| '\\nthort: '+s})
+ident(jbvd)operator(|)ident(g4543ghb)operator(|)operator(!)instance_variable(@G)global_variable($dfsd)operator(|)ident(fafr)operator(|)ident(e)
+operator(|)ident(s4e5rrwware)operator(|)constant(BBBBB)operator(|*)operator(&)operator(^)operator(()operator(*&)operator(^)operator(>)string<delimiter(")content(PMK:njs;d|
+
+foobar1
+})delimiter(")>
+
+reserved(def) method(foo)operator(()ident(a)operator(=)string<delimiter(<<a)>operator(,)ident(b)operator(=)string<delimiter(<<b)>operator(,)ident(c)operator(=)string<delimiter(<<c)>operator(\))string<content(
+jfksdkjf
+dkljjkf)delimiter(
+a)>string<content(
+kdljfjkdg
+dfglkdfkgjdf
+dkf)delimiter(
+b)>string<content(
+lkdffdjksadhf
+sdflkdjgsfdkjgsdg
+dsfg;lkdflisgffd
+g)delimiter(
+c)>
+
+ ident(a)operator(+)ident(b)operator(+)ident(c)
+
+reserved(end)
+ident(p) ident(foo)
+
+
+
+global_variable($a)operator(=)integer(1)
+instance_variable(@b)operator(=)integer(2)
+class_variable(@@c)operator(=)integer(3)
+ident(p) string<delimiter(")escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content( )inline<delimiter(#{)global_variable($a)operator(+)instance_variable(@b)operator(+)class_variable(@@c)delimiter(})>delimiter(")>
+ident(p) string<delimiter(")char(\\#)content($a )char(\\#)content(@b )char(\\#)content(@@c )char(\\#)content({$a+@b+@@c})delimiter(")>
+ident(p) string<delimiter(')content(#$a #@b #@@c #{$a+@b+@@c})delimiter(')>
+ident(p) string<delimiter(')content(\\#)content($a )content(\\#)content(@b )content(\\#)content(@@c )content(\\#)content({$a+@b+@@c})delimiter(')>
+ident(p) string<delimiter(%w")content(#$a #@b #@@c #{$a+@b+@@c})delimiter(")>
+ident(p) string<delimiter(%w")content(\\#)content($a )content(\\#)content(@b )content(\\#)content(@@c )content(\\#)content({$a+@b+@@c})delimiter(")>
+ident(p) string<delimiter(%W")escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content( )inline<delimiter(#{)global_variable($a)operator(+)instance_variable(@b)operator(+)class_variable(@@c)delimiter(})>delimiter(")>
+ident(p) string<delimiter(%W")char(\\#)content($a )char(\\#)content(@b )char(\\#)content(@@c )char(\\#)content({$a+@b+@@c})delimiter(")>
+ident(p) string<delimiter(%Q[)escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content( )inline<delimiter(#{)global_variable($a)operator(+)instance_variable(@b)operator(+)class_variable(@@c)delimiter(})>delimiter(])>
+ident(p) string<delimiter(%Q[)char(\\#)content($a )char(\\#)content(@b )char(\\#)content(@@c )char(\\#)content({$a+@b+@@c})delimiter(])>
+ident(p) shell<delimiter(`)content(echo )escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content( )inline<delimiter(#{)global_variable($a)operator(+)instance_variable(@b)operator(+)class_variable(@@c)delimiter(})>delimiter(`)>
+ident(p) shell<delimiter(`)content(echo )char(\\#)content($a )char(\\#)content(@b )char(\\#)content(@@c )char(\\#)content({$a+@b+@@c})delimiter(`)>
+ident(p)operator(()regexp<delimiter(/)escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content( )inline<delimiter(#{)global_variable($a)operator(+)instance_variable(@b)operator(+)class_variable(@@c)delimiter(})>delimiter(/)>operator(\))
+comment(#p(/\\#$a \\#@b \\#@@c \\#{$a+@b+@@c}/\) #moved to w.rb)
+
+reserved(class) class(AA)operator(;) reserved(class) class(BB)operator(;) reserved(class) class(CC)
+constant(FFOO)operator(=)integer(1)
+reserved(end) reserved(end) reserved(end)
+
+ident(p) constant(AA)operator(::)constant(BB)operator(::)constant(CC)operator(::)constant(FFOO)
+
+ident(compile_body)operator(=)ident(outvar)operator(=)string<delimiter(')content(foob)delimiter(')>
+
+reserved(if) pre_constant(false)
+ ident(method_src) operator(=) ident(c)operator(.)ident(compile)operator(()ident(template)operator(,) operator(()constant(HtmlCompiler)operator(::)constant(AnyData)operator(.)ident(new)operator(\))operator(\))operator(.)ident(join)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\)) operator(+)
+ string<delimiter(")char(\\n)content(# generated by PartsTemplate::compile_partstemplate at )inline<delimiter(#{)constant(Time)operator(.)ident(new)delimiter(})>char(\\n)delimiter(")>
+ ident(rescu) operator(-)integer(1)
+reserved(end)
+
+ ident(p)operator(()string<delimiter(')content(rb_out)delimiter(')>operator(,) string<delimiter(')content(args)delimiter(')>operator(,) string<delimiter(<<-'EOL')>operator(\))string<content(
+ regsub -all {!} $args {)char(\\\\)content(!} args
+ regsub -all "{" $args ")char(\\\\)content({" args
+ if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {
+ return -code $st $ret
+ } {
+ return $ret
+ })delimiter(
+ EOL)>
+
+reserved(def) method(add)operator(()operator(*)ident(args)operator(\))
+ pre_constant(self)operator(.)operator(<<)operator(()operator(*)ident(args)operator(\))
+reserved(end)
+
+
+
+ident(val)operator(=)string<delimiter(%[)content(13,17,22,"hike", ?)char(\\s)delimiter(])>
+ reserved(if) ident(val)operator(.)ident(include?) integer(?\\s)
+ ident(p) ident(val)operator(.)ident(split)operator(.)ident(collect)operator({)operator(|)ident(v)operator(|) operator(()ident(v)operator(\))operator(})
+ reserved(end)
+ident(p) string<delimiter(")inline<delimiter(#{)delimiter(})>delimiter(")>
+ident(p) string<delimiter(")content(#(1\))delimiter(")>
+reserved(class) class(Hosts)
+reserved(end)
+reserved(class) class(DNS) operator(<) constant(Hosts)
+reserved(end)
+reserved(def) method(intialize)operator(()ident(resolvers)operator(=)operator([)constant(Hosts)operator(.)ident(new)operator(,) constant(DNS)operator(.)ident(new)operator(])operator(\)) reserved(end)
+reserved(def) method(environment)operator(()ident(env) operator(=) constant(File)operator(.)ident(basename)operator(()global_variable($0)operator(,) string<delimiter(')content(.*)delimiter(')>operator(\))operator(\)) reserved(end)
+
+reserved(def) method(ssssss) operator(&)ident(block)
+reserved(end)
+reserved(def) method(params_quoted)operator(()ident(field_name)operator(,) ident(default)operator(\))
+ reserved(if) ident(block_given?) reserved(then) reserved(yield) ident(field_name) reserved(else) ident(default) reserved(end)
+reserved(end)
+reserved(def) method(==)operator(()ident(o)operator(\)) integer(444) reserved(end)
+reserved(def) constant(String)operator(.)ident(ffff4)operator(()operator(\)) pre_constant(self)operator(.)ident(to_s)operator(+)string<delimiter(")content(ffff)delimiter(")> reserved(end)
+
+ident(p) operator(*)operator([)operator(])
+reserved(for) ident(i) reserved(in) \
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+comment(#()
+reserved(for) ident(i) reserved(in) reserved(if)
+pre_constant(false) reserved(then) ident(foob12345)operator(;) reserved(else) operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+comment(#\))
+operator(()
+reserved(for) ident(i) reserved(in) reserved(if) pre_constant(false) reserved(then)
+ident(foob12345)operator(;) reserved(else) operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+ident(c)operator(=)ident(j)operator(=)integer(0)
+reserved(until) reserved(while) ident(j)operator(<)integer(10) reserved(do) ident(j)operator(+)operator(=)integer(1) reserved(end)operator(.)ident(nil?) reserved(do) ident(p) string<delimiter(')content(pppppppppp)delimiter(')> reserved(end)
+reserved(for) ident(i) reserved(in) reserved(if) pre_constant(false) reserved(then) ident(foob12345)operator(;)
+reserved(else) operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+reserved(for) ident(i) reserved(in) reserved(if) pre_constant(false) reserved(then) ident(foob12345)operator(;) reserved(else)
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+
+reserved(for) ident(i) reserved(in) operator(()ident(c)operator(;)
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(])operator(\)) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+operator(\))
+operator(()
+
+reserved(for) ident(i) reserved(in) operator(()reserved(begin)
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end)operator(\)) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+reserved(for) ident(i) reserved(in) reserved(if) pre_constant(false) reserved(then) ident(foob12345)operator(;) reserved(else)
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+reserved(for) ident(i) reserved(in) operator(()
+
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(])operator(\)) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+reserved(for) ident(i) reserved(in) operator(()
+operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(])operator(\)) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+
+operator(\))
+
+
+reserved(def) method(yy)operator(;)reserved(yield) reserved(end)
+
+ident(block)operator(=)ident(proc)operator({)ident(p) string<delimiter(")content(blah blah)delimiter(")>operator(})
+
+ident(yy) operator(&)ident(block)
+ident(p)operator(()integer(1)operator(.)operator(+)integer(1)operator(\))
+ident(p) ident(pppp)
+
+reserved(module) class(M66)
+ident(p)operator(()ident(proc) reserved(do)
+ ident(p)operator(=)integer(123)
+reserved(end)operator(.)ident(call)operator(\))
+
+ident(p) ident(proc) operator({)
+ ident(p)operator(=)integer(123)
+operator(})operator(.)ident(call)
+
+ident(p) reserved(def) method(pppp)
+ ident(p)operator(=)integer(123)
+reserved(end)
+ident(p) reserved(module) class(Ppp)
+ ident(p)operator(=)integer(123)
+reserved(end)
+ident(p) reserved(class) class(Pppp) operator(<) constant(String)
+ ident(p)operator(=)integer(123)
+reserved(end)
+reserved(end)
+
+ reserved(def) method(_make_regex)operator(()ident(str)operator(\)) operator(/)operator(()operator([)comment(#{Regexp.escape(str\)}]\)/n end)
+ident(p) ident(_make_regex)operator(()string<delimiter(")content(8smdf,34rh)char(\\#)content(@)char(\\#)content($%$gfm/[]dD)delimiter(")>operator(\))
+
+
+ident(p) string<delimiter(")escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content(
+
+d e f
+)escape(#)global_variable($a)content( )escape(#)instance_variable(@b)content( )escape(#)class_variable(@@c)content(
+)delimiter(")>
+
+ident(p) string<delimiter(")char(\\")delimiter(")>
+
+ident(a)operator(=)ident(a)operator(.)ident(to_s)
+reserved(class) operator(<<)class(a)
+ reserved(def) method(foobar)
+ pre_constant(self)operator(*)integer(101)
+ reserved(end)
+ reserved(alias) ident(eql?) operator(==)
+reserved(end)
+
+ident(p) ident(a)operator(.)ident(foobar)
+
+ident(p)operator(()regexp<delimiter(/)content(^)char(\\s)content(*(([+-)char(\\/)content(*&)char(\\|)content(^]|<<|>>|)char(\\|)char(\\|)content(|)char(\\&)char(\\&)content(\)=|)char(\\&)char(\\&)content(|)char(\\|)char(\\|)content(\))delimiter(/)>operator(\))
+ident(p)operator(()symbol(:%)operator(\))
+ident(p)operator(() operator({) symbol(:class) operator(=)operator(>) ident(class_)operator(=)integer(0)operator(})operator(\))
+ident(p) ident(cls_name) operator(=) operator({)operator(})operator([)symbol(:class)operator(])
+
+
+ident(p) ident(foo)
+ident(p) string<delimiter(")inline<delimiter(#{)global_variable($!)operator(.)ident(class)delimiter(})>delimiter(")>
+ident(p) symbol(:p)
+ident(p)operator(()symbol(:p)operator(\))
+ident(p)operator(()symbol<symbol(:)delimiter(")content([])delimiter(")>operator(\))
+ident(p) symbol<symbol(:)delimiter(")content([])delimiter(")>
+ident(p)operator(()string<delimiter(")char(\\\\)delimiter(")>operator(\))
+ident(p)operator(()regexp<delimiter(/)char(\\\\)delimiter(/)>operator(\))
+ident(p)operator(()regexp<delimiter(/)content([)char(\\\\)content(])delimiter(/)>operator(\))
+ident(p) integer(0x80)
+ident(p) integer(?p)
+ident(p) float(0.1)
+ident(p) float(0.8)
+ident(p) float(0.9)
+ident(p)operator(()operator(-)integer(1)operator(\))
+ident(p) string<delimiter(%/)content(p)delimiter(/)>
+ident(p) string<delimiter(%Q[)content(<LI>)delimiter(])>
+ident(i)operator(=)integer(99)
+ident(p) string<delimiter(%Q[)content(<LI><A HREF=")inline<delimiter(#{)ident(i)operator([)integer(3)operator(])delimiter(})>content(.html)char(\\#)inline<delimiter(#{)ident(i)operator([)integer(4)operator(])delimiter(})>content(">)inline<delimiter(#{)ident(i)operator([)integer(0)operator(])operator(+)ident(i)operator([)integer(1)operator(])operator(+)operator(()ident(i)operator([)integer(2)operator(])operator(\))delimiter(})>content(</A>)char(\\n)delimiter(])>
+ident(p)operator(()symbol(:side=)operator(>)symbol(:top)operator(\))
+ident(p) string<delimiter(%w[)content(a b c
+ d e f)delimiter(])>
+ident(p) string<delimiter(%w[)content(a b c)content(\\n)content(
+ d e f)delimiter(])>
+ident(p) string<delimiter(%w[)char(\\\\)delimiter(])>
+ident(p) string<delimiter(%w[)char(\\])delimiter(])>
+ident(p) symbol(:+)
+ident(p) integer(99) operator(/) integer(3)
+
+ident(a)operator(=)integer(99)operator(;)ident(b)operator(=)integer(3)
+ident(p) integer(1)operator(+)operator(()ident(a) operator(/) ident(b)operator(\))
+ident(p) string<delimiter(%Q[)char(\\")delimiter(])>
+ident(p) string<delimiter(%Q[)content( some )nesting_delimiter([)content(nested)nesting_delimiter(])content( text)delimiter(])>
+
+reserved(if) pre_constant(false)
+ ident(formatter)operator(.)ident(format_element)operator(()ident(element)operator(\)) reserved(do)
+ ident(amrita_expand_and_format1)operator(()ident(element)operator(,) ident(context)operator(,) ident(formatter)operator(\))
+ reserved(end)
+reserved(end)
+reserved(if) pre_constant(false)
+ ident(ret) operator(=) string<delimiter(<<-END)>string<content(
+ @@parts_template = )inline<delimiter(#{)ident(template)operator(.)ident(to_ruby)delimiter(})>content(
+ def parts_template
+ @@parts_template
+ end
+
+ )inline<delimiter(#{)ident(c)operator(.)ident(const_def_src)operator(.)ident(join)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\))delimiter(})>content(
+ def amrita_expand_and_format(element, context, formatter\)
+ if element.tagname_symbol == :span and element.attrs.size == 0
+ amrita_expand_and_format1(element, context, formatter\)
+ else
+ formatter.format_element(element\) do
+ amrita_expand_and_format1(element, context, formatter\)
+ end
+ end
+ end
+
+ def amrita_expand_and_format1(element, context, formatter\)
+ )inline<delimiter(#{)ident(method_src)delimiter(})>content(
+ end)delimiter(
+ END)>
+ ident(j)operator(=)integer(55)
+reserved(end)
+
+ident(p) string<delimiter(')content(
+)delimiter(')>
+ident(p) string<delimiter(')content(\\n)delimiter(')>
+ident(p) string<delimiter(")content(
+)delimiter(")>
+ident(p) string<delimiter(")char(\\n)delimiter(")>
+ident(p) string<delimiter(%w/)content(
+)delimiter(/)>
+ident(p) string<delimiter(%w/)content(\\n)delimiter(/)>
+
+ident(p) string<delimiter(%W/)content(
+)delimiter(/)>
+ident(p) string<delimiter(%W/)char(\\n)delimiter(/)>
+ident(p)operator(()regexp<delimiter(/)content(
+)delimiter(/)>operator(\))
+ident(p)operator(()regexp<delimiter(/)char(\\n)delimiter(/)>operator(\))
+ident(p) ident(proc) operator({)
+ ident(p) shell<delimiter(`)content(
+ )delimiter(`)>
+ ident(p) shell<delimiter(`)char(\\n)delimiter(`)>
+operator(})
+
+
+
+ident(p)operator(()regexp<delimiter(%r[)content(foo)delimiter(])modifier(i)>operator(\))
+comment(#breakpoint)
+ident(p) string<delimiter(<<stuff)>operator(+)string<delimiter(')content(foobar)delimiter(')>operator(.)ident(tr)operator(()string<delimiter(')content(j-l)delimiter(')>operator(,)string<delimiter(')content(d-f)delimiter(')>operator(\))string<content(
+"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog)delimiter(
+stuff)>
+
+comment(=begin doesn't work
+p <<stuff+'foobar'.tr('j-l','d-f'\)\\
++"more stuff"
+12345678
+the quick brown fox jumped over the lazy dog
+stuff
+=end)
+
+ident(p) constant(ENV)operator([)string<delimiter(")content(AmritaCacheDir)delimiter(")>operator(])
+ident(p) string<delimiter(<<-BEGIN)> operator(+) string<delimiter(<<-END)>string<content(
+ def element_downcase(attributes = {}\))delimiter(
+ BEGIN)>string<content(
+ end)delimiter(
+ END)>
+
+
+
+ident(p) string<delimiter(<<ggg)>operator(;) reserved(def)string<content(
+kleegarts(\) p 'kkkkkkk' end
+dfgdgfdf)delimiter(
+ggg)>
+ident(koomblatz!)operator(()operator(\)) ident(p) string<delimiter(')content(jdkfsk)delimiter(')> reserved(end)
+
+ident(koomblatz!)
+
+ident(p) ident(f) operator(=) float(3.7517675036461267e+17)
+ident(p) global_variable($10)
+ident(p) global_variable($1001)
+ident(p)operator(() string<delimiter(<<end)> operator(\))string<content(
+nine time nine men have stood untold.)delimiter(
+end)>
+
+reserved(def) method(jd_to_wday)operator(()ident(jd)operator(\)) operator(()ident(jd) operator(+) integer(1)operator(\)) operator(%) integer(7) reserved(end)
+ident(p) ident(jd_to_wday)operator(()integer(98)operator(\))
+
+
+ident(p) ident(pre) operator(=) global_variable($`)
+comment(=begin
+=end)
+
+ident(p) string<delimiter(<<"..end ..")>string<content(
+cbkvjb
+vb;lkxcvkbxc
+vxlc;kblxckvb
+xcvblcvb)delimiter(
+..end ..)>
+
+ident(p) global_variable($-j)operator(=)integer(55)
+
+reserved(def) method(empty)operator(()operator(\)) reserved(end)
+
+ident(p) string<delimiter(<<a)>string<content(
+dkflg
+flk)delimiter(
+a)>
+
+ident(label)operator(=)string<delimiter(')content(label)delimiter(')>operator(;)ident(tab)operator(=)operator([)integer(1)operator(,)integer(2)operator(,)integer(3)operator(])
+ ident(p) string<delimiter(<<S)>string<content(
+)inline<delimiter(#{)ident(label)delimiter(})>content( = arr = Array.new()inline<delimiter(#{)ident(tab)operator(.)ident(size)delimiter(})>content(, nil\)
+str = a = i = nil
+idx = 0
+clist.each do |str|
+ str.split(',', -1\).each do |i|
+ arr[idx] = i.to_i unless i.empty?
+ idx += 1
+ end
+end
+)delimiter(
+S)>
+reserved(def) method(printem1) ident(a)operator(,)ident(b)operator(,)ident(c)
+ ident(p)operator(()ident(a) operator(+)integer(77)operator(\))
+ ident(p)operator(()ident(b) operator(+)integer(77)operator(\))
+ ident(p)operator(()ident(c) operator(+)integer(77)operator(\))
+reserved(end)
+
+reserved(def) method(foobar)operator(()operator(\)) reserved(end)
+reserved(def) method(foobar2)
+reserved(end)
+
+reserved(def) method(printem0)operator(()ident(a)operator(\))
+ ident(p)operator(()ident(a) operator(+)integer(77)operator(\))
+reserved(end)
+reserved(def) method(printem0)operator(()ident(a)operator(,)ident(b)operator(,)ident(c)operator(\))
+ ident(p)operator(()ident(a) operator(+)integer(77)operator(\))
+ ident(p)operator(()ident(b) operator(+)integer(77)operator(\))
+ ident(p)operator(()ident(c) operator(+)integer(77)operator(\))
+reserved(end)
+reserved(def) method(printem2) ident(a)operator(,)ident(b)operator(,)ident(c)operator(;) ident(p)operator(()ident(a) operator(+)integer(77)operator(\))operator(;) ident(p)operator(()ident(b) operator(+)integer(77)operator(\))operator(;) ident(p)operator(()ident(c) operator(+)integer(77)operator(\)) reserved(end)
+reserved(def) method(three)operator(()operator(\)) operator(()integer(1)operator(+)integer(2)operator(\)) reserved(end)
+
+reserved(def) method(d)operator(;)reserved(end)
+reserved(def) method(d)operator(()operator(\))reserved(end)
+reserved(def) method(d)operator(()ident(dd)operator(\))reserved(end)
+
+reserved(def) method(printem) ident(a)operator(,)ident(b)operator(,)ident(c)
+ ident(p) ident(a)operator(;)ident(p) ident(b)operator(;)ident(p) ident(c)
+ ident(p)operator(()ident(a) operator(+)integer(77)operator(\))
+ ident(p)operator(()ident(b) string<delimiter(%()content(0.123)delimiter(\))>operator(\))
+reserved(end)
+ident(printem) integer(1)operator(,)integer(2)operator(,)integer(3)
+
+ident(a)operator(=)integer(1)
+ident(p)operator(()ident(a) operator(+)integer(77)operator(\))
+
+reserved(def) method(hhh)operator(()ident(a)operator(=)operator(()integer(1)operator(+)integer(2)operator(\))operator(\)) ident(a) reserved(end)
+
+
+
+reserved(END) operator({)
+ ident(p) string<delimiter(")content(bye-bye)delimiter(")>
+operator(})
+
+
+ident(p) string<delimiter(<<here)>string<content(
+where?)delimiter(
+here)>
+ident(p) string<delimiter(<<-what)>string<content(
+ ? that's)delimiter(
+ what)>
+ident(p) ident(proc)operator({)operator(||)operator(})
+reserved(for) ident(i) reserved(in) reserved(if) pre_constant(false)
+ident(foob12345)operator(;) reserved(else) operator([)integer(44)operator(,)integer(55)operator(,)integer(66)operator(,)integer(77)operator(,)integer(88)operator(]) reserved(end) reserved(do) ident(p) ident(i)operator(**)constant(Math)operator(.)ident(sqrt)operator(()ident(i)operator(\)) reserved(end)
+ident(p) string<delimiter(")char(\\v)delimiter(")>
+ident(c)operator(=)integer(0)
+ reserved(while) ident(c) operator(==) regexp<delimiter(/)content([ )char(\\t)char(\\f)char(\\r)char(\\13)content(])delimiter(/)>operator(;) reserved(end)
+
+
+
+
+
+
+
+
diff --git a/test/ruby/pleac.in.rb b/test/ruby/pleac.in.rb new file mode 100644 index 0000000..0f967b9 --- /dev/null +++ b/test/ruby/pleac.in.rb @@ -0,0 +1,6368 @@ +# -*- ruby -*- + +# Local variables: +# indent-tabs-mode: nil +# ruby-indent-level: 4 +# End: + +# @@PLEAC@@_NAME +# @@SKIP@@ Ruby + +# @@PLEAC@@_WEB +# @@SKIP@@ http://www.ruby-lang.org + + +# @@PLEAC@@_1.0 +string = '\n' # two characters, \ and an n +string = 'Jon \'Maddog\' Orwant' # literal single quotes + +string = "\n" # a "newline" character +string = "Jon \"Maddog\" Orwant" # literal double quotes + +string = %q/Jon 'Maddog' Orwant/ # literal single quotes + +string = %q[Jon 'Maddog' Orwant] # literal single quotes +string = %q{Jon 'Maddog' Orwant} # literal single quotes +string = %q(Jon 'Maddog' Orwant) # literal single quotes +string = %q<Jon 'Maddog' Orwant> # literal single quotes + +a = <<"EOF" +This is a multiline here document +terminated by EOF on a line by itself +EOF + + +# @@PLEAC@@_1.1 +value = string[offset,count] +value = string[offset..-1] + +string[offset,count] = newstring +string[offset..-1] = newtail + +# in Ruby we can also specify intervals by their two offsets +value = string[offset..offs2] +string[offset..offs2] = newstring + +leading, s1, s2, trailing = data.unpack("A5 x3 A8 A8 A*") + +fivers = string.unpack("A5" * (string.length/5)) + +chars = string.unpack("A1" * string.length) + +string = "This is what you have" +# +012345678901234567890 Indexing forwards (left to right) +# 109876543210987654321- Indexing backwards (right to left) +# note that 0 means 10 or 20, etc. above + +first = string[0, 1] # "T" +start = string[5, 2] # "is" +rest = string[13..-1] # "you have" +last = string[-1, 1] # "e" +end_ = string[-4..-1] # "have" +piece = string[-8, 3] # "you" + +string[5, 2] = "wasn't" # change "is" to "wasn't" +string[-12..-1] = "ondrous" # "This wasn't wondrous" +string[0, 1] = "" # delete first character +string[-10..-1] = "" # delete last 10 characters + +if string[-10..-1] =~ /pattern/ + puts "Pattern matches in last 10 characters" +end + +string[0, 5].gsub!(/is/, 'at') + +a = "make a hat" +a[0, 1], a[-1, 1] = a[-1, 1], a[0, 1] + +a = "To be or not to be" +b = a.unpack("x6 A6") + +b, c = a.unpack("x6 A2 X5 A2") +puts "#{b}\n#{c}\n" + +def cut2fmt(*args) + template = '' + lastpos = 1 + for place in args + template += "A" + (place - lastpos).to_s + " " + lastpos = place + end + template += "A*" + return template +end + +fmt = cut2fmt(8, 14, 20, 26, 30) + + +# @@PLEAC@@_1.2 +# careful! "b is true" doesn't mean "b != 0" (0 is true in Ruby) +# thus no problem of "defined" later since only nil is false +# the following sets to `c' if `b' is nil or false +a = b || c + +# if you need Perl's behaviour (setting to `c' if `b' is 0) the most +# effective way is to use Numeric#nonzero? (thanks to Dave Thomas!) +a = b.nonzero? || c + +# you will still want to use defined? in order to test +# for scope existence of a given object +a = defined?(b) ? b : c + +dir = ARGV.shift || "/tmp" + + +# @@PLEAC@@_1.3 +v1, v2 = v2, v1 + +alpha, beta, production = %w(January March August) +alpha, beta, production = beta, production, alpha + + +# @@PLEAC@@_1.4 +num = char[0] +char = num.chr + +# Ruby also supports having a char from character constant +num = ?r + +char = sprintf("%c", num) +printf("Number %d is character %c\n", num, num) + +ascii = string.unpack("C*") +string = ascii.pack("C*") + +hal = "HAL" +ascii = hal.unpack("C*") +# We can't use Array#each since we can't mutate a Fixnum +ascii.collect! { |i| + i + 1 # add one to each ASCII value +} +ibm = ascii.pack("C*") +puts ibm + + +# @@PLEAC@@_1.5 +array = string.split('') + +array = string.unpack("C*") + +string.scan(/./) { |b| + # do something with b +} + +string = "an apple a day" +print "unique chars are: ", string.split('').uniq.sort, "\n" + +sum = 0 +for ascval in string.unpack("C*") # or use Array#each for a pure OO style :) + sum += ascval +end +puts "sum is #{sum & 0xffffffff}" # since Ruby will go Bignum if necessary + +# @@INCLUDE@@ include/ruby/slowcat.rb + + +# @@PLEAC@@_1.6 +revbytes = string.reverse + +revwords = string.split(" ").reverse.join(" ") + +revwords = string.split(/(\s+)/).reverse.join + +# using the fact that IO is Enumerable, you can directly "select" it +long_palindromes = File.open("/usr/share/dict/words"). + select { |w| w.chomp!; w.reverse == w && w.length > 5 } + + +# @@PLEAC@@_1.7 +while string.sub!("\t+") { ' ' * ($&.length * 8 - $`.length % 8) } +end + + +# @@PLEAC@@_1.8 +'You owe #{debt} to me'.gsub(/\#{(\w+)}/) { eval($1) } + +rows, cols = 24, 80 +text = %q(I am #{rows} high and #{cols} long) +text.gsub!(/\#{(\w+)}/) { eval("#{$1}") } +puts text + +'I am 17 years old'.gsub(/\d+/) { 2 * $&.to_i } + + +# @@PLEAC@@_1.9 +e = "bo peep".upcase +e.downcase! +e.capitalize! + +"thIS is a loNG liNE".gsub!(/\w+/) { $&.capitalize } + + +# @@PLEAC@@_1.10 +"I have #{n+1} guanacos." +print "I have ", n+1, " guanacos." + + +# @@PLEAC@@_1.11 +var = <<'EOF'.gsub(/^\s+/, '') + your text + goes here +EOF + + +# @@PLEAC@@_1.12 +string = "Folding and splicing is the work of an editor,\n"+ + "not a mere collection of silicon\n"+ + "and\n"+ + "mobile electrons!" + +def wrap(str, max_size) + all = [] + line = '' + for l in str.split + if (line+l).length >= max_size + all.push(line) + line = '' + end + line += line == '' ? l : ' ' + l + end + all.push(line).join("\n") +end + +print wrap(string, 20) +#=> Folding and +#=> splicing is the +#=> work of an editor, +#=> not a mere +#=> collection of +#=> silicon and mobile +#=> electrons! + + +# @@PLEAC@@_1.13 +string = %q(Mom said, "Don't do that.") +string.gsub(/['"]/) { '\\'+$& } +string.gsub(/['"]/, '\&\&') +string.gsub(/[^A-Z]/) { '\\'+$& } +"is a test!".gsub(/\W/) { '\\'+$& } # no function like quotemeta? + + +# @@PLEAC@@_1.14 +string.strip! + + +# @@PLEAC@@_1.15 +def parse_csv(text) + new = text.scan(/"([^\"\\]*(?:\\.[^\"\\]*)*)",?|([^,]+),?|,/) + new << nil if text[-1] == ?, + new.flatten.compact +end + +line = %q<XYZZY,"","O'Reilly, Inc","Wall, Larry","a \"glug\" bit,",5,"Error, Core Dumped"> +fields = parse_csv(line) +fields.each_with_index { |v,i| + print "#{i} : #{v}\n"; +} + + +# @@PLEAC@@_1.16 +# Use the soundex.rb Library from Michael Neumann. +# http://www.s-direktnet.de/homepages/neumann/rb_prgs/Soundex.rb +require 'Soundex' + +code = Text::Soundex.soundex(string) +codes = Text::Soundex.soundex(array) + +# substitution function for getpwent(): +# returns an array of user entries, +# each entry contains the username and the full name +def login_names + result = [] + File.open("/etc/passwd") { |file| + file.each_line { |line| + next if line.match(/^#/) + cols = line.split(":") + result.push([cols[0], cols[4]]) + } + } + result +end + +puts "Lookup user: " +user = STDIN.gets +user.chomp! +exit unless user +name_code = Text::Soundex.soundex(user) + +splitter = Regexp.new('(\w+)[^,]*\b(\w+)') +for username, fullname in login_names do + firstname, lastname = splitter.match(fullname)[1,2] + if name_code == Text::Soundex.soundex(username) + || name_code == Text::Soundex.soundex(firstname) + || name_code == Text::Soundex.soundex(lastname) + then + puts "#{username}: #{firstname} #{lastname}" + end +end + + +# @@PLEAC@@_1.17 +# @@INCLUDE@@ include/ruby/fixstyle.rb + + +# @@PLEAC@@_1.18 +# @@INCLUDE@@ include/ruby/psgrep.rb + + +# @@PLEAC@@_2.1 +# Matz tells that you can use Integer() for strict checked conversion. +Integer("abc") +#=> `Integer': invalid value for Integer: "abc" (ArgumentError) +Integer("567") +#=> 567 + +# You may use Float() for floating point stuff +Integer("56.7") +#=> `Integer': invalid value for Integer: "56.7" (ArgumentError) +Float("56.7") +#=> 56.7 + +# You may also use a regexp for that +if string =~ /^[+-]?\d+$/ + p 'is an integer' +else + p 'is not' +end + +if string =~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/ + p 'is a decimal number' +else + p 'is not' +end + + +# @@PLEAC@@_2.2 +# equal(num1, num2, accuracy) : returns true if num1 and num2 are +# equal to accuracy number of decimal places +def equal(i, j, a) + sprintf("%.#{a}g", i) == sprintf("%.#{a}g", j) +end + +wage = 536 # $5.36/hour +week = 40 * wage # $214.40 +printf("One week's wage is: \$%.2f\n", week/100.0) + + +# @@PLEAC@@_2.3 +num.round # rounds to integer + +a = 0.255 +b = sprintf("%.2f", a) +print "Unrounded: #{a}\nRounded: #{b}\n" +printf "Unrounded: #{a}\nRounded: %.2f\n", a + +print "number\tint\tfloor\tceil\n" +a = [ 3.3 , 3.5 , 3.7, -3.3 ] +for n in a + printf("% .1f\t% .1f\t% .1f\t% .1f\n", # at least I don't fake my output :) + n, n.to_i, n.floor, n.ceil) +end + + +# @@PLEAC@@_2.4 +def dec2bin(n) + [n].pack("N").unpack("B32")[0].sub(/^0+(?=\d)/, '') +end + +def bin2dec(n) + [("0"*32+n.to_s)[-32..-1]].pack("B32").unpack("N")[0] +end + + +# @@PLEAC@@_2.5 +for i in x .. y + # i is set to every integer from x to y, inclusive +end + +x.step(y,7) { |i| + # i is set to every integer from x to y, stepsize = 7 +} + +print "Infancy is: " +(0..2).each { |i| + print i, " " +} +print "\n" + + +# @@PLEAC@@_2.6 +# We can add conversion methods to the Integer class, +# this makes a roman number just a representation for normal numbers. +class Integer + + @@romanlist = [["M", 1000], + ["CM", 900], + ["D", 500], + ["CD", 400], + ["C", 100], + ["XC", 90], + ["L", 50], + ["XL", 40], + ["X", 10], + ["IX", 9], + ["V", 5], + ["IV", 4], + ["I", 1]] + + def to_roman + remains = self + roman = "" + for sym, num in @@romanlist + while remains >= num + remains -= num + roman << sym + end + end + roman + end + + def Integer.from_roman(roman) + ustr = roman.upcase + sum = 0 + for entry in @@romanlist + sym, num = entry[0], entry[1] + while sym == ustr[0, sym.length] + sum += num + ustr.slice!(0, sym.length) + end + end + sum + end + +end + + +roman_fifteen = 15.to_roman +puts "Roman for fifteen is #{roman_fifteen}" +i = Integer.from_roman(roman_fifteen) +puts "Converted back, #{roman_fifteen} is #{i}" + +# check +for i in (1..3900) + r = i.to_roman + j = Integer.from_roman(r) + if i != j + puts "error: #{i} : #{r} - #{j}" + end +end + + +# @@PLEAC@@_2.7 +random = rand(y-x+1)+x + +chars = ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!@$%^&*) +password = (1..8).collect { chars[rand(chars.size)] }.pack("C*") + + +# @@PLEAC@@_2.8 +srand # uses a combination of the time, the process id, and a sequence number +srand(val) # for repeatable behaviour + + +# @@PLEAC@@_2.9 +# from the randomr lib: +# http://raa.ruby-lang.org/project/randomr/ +----> http://raa.ruby-lang.org/project/randomr/ + +require 'random/mersenne_twister' +mers = Random::MersenneTwister.new 123456789 +puts mers.rand(0) # 0.550321932544541 +puts mers.rand(10) # 2 + +# using online sources of random data via the realrand package: +# http://raa.ruby-lang.org/project/realrand/ +# **Note** +# The following online services are used in this package: +# http://www.random.org - source: atmospheric noise +# http://www.fourmilab.ch/hotbits - source: radioactive decay timings +# http://random.hd.org - source: entropy from local and network noise +# Please visit the sites and respect the rules of each service. + +require 'random/online' + +generator1 = Random::RandomOrg.new +puts generator1.randbyte(5).join(",") +puts generator1.randnum(10, 1, 6).join(",") # Roll dice 10 times. + +generator2 = Random::FourmiLab.new +puts generator2.randbyte(5).join(",") +# randnum is not supported. + +generator3 = Random::EntropyPool.new +puts generator3.randbyte(5).join(",") +# randnum is not supported. + + +# @@PLEAC@@_2.10 +def gaussian_rand + begin + u1 = 2 * rand() - 1 + u2 = 2 * rand() - 1 + w = u1*u1 + u2*u2 + end while (w >= 1) + w = Math.sqrt((-2*Math.log(w))/w) + [ u2*w, u1*w ] +end + +mean = 25 +sdev = 2 +salary = gaussian_rand[0] * sdev + mean +printf("You have been hired at \$%.2f\n", salary) + + +# @@PLEAC@@_2.11 +def deg2rad(d) + (d/180.0)*Math::PI +end + +def rad2deg(r) + (r/Math::PI)*180 +end + + +# @@PLEAC@@_2.12 +sin_val = Math.sin(angle) +cos_val = Math.cos(angle) +tan_val = Math.tan(angle) + +# AFAIK Ruby's Math module doesn't provide acos/asin +# While we're at it, let's also define missing hyperbolic functions +module Math + def Math.asin(x) + atan2(x, sqrt(1 - x**2)) + end + def Math.acos(x) + atan2(sqrt(1 - x**2), x) + end + def Math.atan(x) + atan2(x, 1) + end + def Math.sinh(x) + (exp(x) - exp(-x)) / 2 + end + def Math.cosh(x) + (exp(x) + exp(-x)) / 2 + end + def Math.tanh(x) + sinh(x) / cosh(x) + end +end + +# The support for Complex numbers is not built-in +y = Math.acos(3.7) +#=> in `sqrt': square root for negative number (ArgumentError) + +# There is an implementation of Complex numbers in 'complex.rb' in current +# Ruby distro, but it doesn't support atan2 with complex args, so it doesn't +# solve this problem. + + +# @@PLEAC@@_2.13 +log_e = Math.log(val) +log_10 = Math.log10(val) + +def log_base(base, val) + Math.log(val)/Math.log(base) +end + +answer = log_base(10, 10_000) +puts "log10(10,000) = #{answer}" + + +# @@PLEAC@@_2.14 +require 'matrix.rb' + +a = Matrix[[3, 2, 3], [5, 9, 8]] +b = Matrix[[4, 7], [9, 3], [8, 1]] +c = a * b + +a.row_size +a.column_size + +c.det +a.transpose + + +# @@PLEAC@@_2.15 +require 'complex.rb' +require 'rational.rb' + +a = Complex(3, 5) # 3 + 5i +b = Complex(2, -2) # 2 - 2i +puts "c = #{a*b}" + +c = a * b +d = 3 + 4*Complex::I + +printf "sqrt(#{d}) = %s\n", Math.sqrt(d) + + +# @@PLEAC@@_2.16 +number = hexadecimal.hex +number = octal.oct + +print "Gimme a number in decimal, octal, or hex: " +num = gets.chomp +exit unless defined?(num) +num = num.oct if num =~ /^0/ # does both oct and hex +printf "%d %x %o\n", num, num, num + +print "Enter file permission in octal: " +permissions = gets.chomp +raise "Exiting ...\n" unless defined?(permissions) +puts "The decimal value is #{permissions.oct}" + + +# @@PLEAC@@_2.17 +def commify(n) + n.to_s =~ /([^\.]*)(\..*)?/ + int, dec = $1.reverse, $2 ? $2 : "" + while int.gsub!(/(,|\.|^)(\d{3})(\d)/, '\1\2,\3') + end + int.reverse + dec +end + + +# @@PLEAC@@_2.18 +printf "It took %d hour%s\n", time, time == 1 ? "" : "s" + +# dunno if an equivalent to Lingua::EN::Inflect exists... + + +# @@PLEAC@@_2.19 +#----------------------------- +#!/usr/bin/ruby +# bigfact - calculating prime factors +def factorize(orig) + factors = {} + factors.default = 0 # return 0 instead nil if key not found in hash + n = orig + i = 2 + sqi = 4 # square of i + while sqi <= n do + while n.modulo(i) == 0 do + n /= i + factors[i] += 1 + # puts "Found factor #{i}" + end + # we take advantage of the fact that (i +1)**2 = i**2 + 2*i +1 + sqi += 2 * i + 1 + i += 1 + end + + if (n != 1) && (n != orig) + factors[n] += 1 + end + factors +end + +def printfactorhash(orig, factorcount) + print format("%-10d ", orig) + if factorcount.length == 0 + print "PRIME" + else + # sorts after number, because the hash keys are numbers + factorcount.sort.each { |factor,exponent| + print factor + if exponent > 1 + print "**", exponent + end + print " " + } + end + puts +end + +for arg in ARGV + n = arg.to_i + mfactors = factorize(n) + printfactorhash(n, mfactors) +end +#----------------------------- + + +# @@PLEAC@@_3.0 +puts Time.now + +print "Today is day ", Time.now.yday, " of the current year.\n" +print "Today is day ", Time.now.day, " of the current month.\n" + + +# @@PLEAC@@_3.1 +day, month, year = Time.now.day, Time.now.month, Time.now.year +# or +day, month, year = Time.now.to_a[3..5] + +tl = Time.now.localtime +printf("The current date is %04d %02d %02d\n", tl.year, tl.month, tl.day) + +Time.now.localtime.strftime("%Y-%m-%d") + + +# @@PLEAC@@_3.2 +Time.local(year, month, day, hour, minute, second).tv_sec +Time.gm(year, month, day, hour, minute, second).tv_sec + + +# @@PLEAC@@_3.3 +sec, min, hour, day, month, year, wday, yday, isdst, zone = Time.at(epoch_secs).to_a + + +# @@PLEAC@@_3.4 +when_ = now + difference # now -> Time ; difference -> Numeric (delta in seconds) +then_ = now - difference + + +# @@PLEAC@@_3.5 +bree = 361535725 +nat = 96201950 + +difference = bree - nat +puts "There were #{difference} seconds between Nat and Bree" + +seconds = difference % 60 +difference = (difference - seconds) / 60 +minutes = difference % 60 +difference = (difference - minutes) / 60 +hours = difference % 24 +difference = (difference - hours) / 24 +days = difference % 7 +weeks = (difference - days) / 7 + +puts "(#{weeks} weeks, #{days} days, #{hours}:#{minutes}:#{seconds})" + + +# @@PLEAC@@_3.6 +monthday, weekday, yearday = date.mday, date.wday, date.yday + +# AFAIK the week number is not just a division since week boundaries are on sundays +weeknum = d.strftime("%U").to_i + 1 + +year = 1981 +month = "jun" # or `6' if you want to emulate a broken language +day = 16 +t = Time.mktime(year, month, day) +print "#{month}/#{day}/#{year} was a ", t.strftime("%A"), "\n" + + +# @@PLEAC@@_3.7 +yyyy, mm, dd = $1, $2, $3 if "1998-06-25" =~ /(\d+)-(\d+)-(\d+)/ + +epoch_seconds = Time.mktime(yyyy, mm, dd).tv_sec + +# dunno an equivalent to Date::Manip#ParseDate + + +# @@PLEAC@@_3.8 +string = Time.at(epoch_secs) +Time.at(1234567890).gmtime # gives: Fri Feb 13 23:31:30 UTC 2009 + +time = Time.mktime(1973, "jan", 18, 3, 45, 50) +print "In localtime it gives: ", time.localtime, "\n" + + +# @@PLEAC@@_3.9 +# Ruby provides micro-seconds in Time object +Time.now.usec + +# Ruby gives the seconds in floating format when substracting two Time objects +before = Time.now +line = gets +elapsed = Time.now - before +puts "You took #{elapsed} seconds." + +# On my Celeron-400 with Linux-2.2.19-14mdk, average for three execs are: +# This Ruby version: average 0.00321 sec +# Cookbook's Perl version: average 0.00981 sec +size = 500 +number_of_times = 100 +total_time = 0 +number_of_times.times { + # populate array + array = [] + size.times { array << rand } + # sort it + begin_ = Time.now + array.sort! + time = Time.now - begin_ + total_time += time +} +printf "On average, sorting %d random numbers takes %.5f seconds\n", + size, (total_time/Float(number_of_times)) + + +# @@PLEAC@@_3.10 +sleep(0.005) # Ruby is definitely not as broken as Perl :) +# (may be interrupted by sending the process a SIGALRM) + + +# @@PLEAC@@_3.11 +#!/usr/bin/ruby -w +# hopdelta - feed mail header, produce lines +# showing delay at each hop. +require 'time' +class MailHopDelta + + def initialize(mail) + @head = mail.gsub(/\n\s+/,' ') + @topline = %w-Sender Recipient Time Delta- + @start_from = mail.match(/^From.*\@([^\s>]*)/)[1] + @date = Time.parse(mail.match(/^Date:\s+(.*)/)[1]) + end + + def out(line) + "%-20.20s %-20.20s %-20.20s %s" % line + end + + def hop_date(day) + day.strftime("%I:%M:%S %Y/%m/%d") + end + + def puts_hops + puts out(@topline) + puts out(['Start', @start_from, hop_date(@date),'']) + @head.split(/\n/).reverse.grep(/^Received:/).each do |hop| + hop.gsub!(/\bon (.*?) (id.*)/,'; \1') + whence = hop.match(/;\s+(.*)$/)[1] + unless whence + warn "Bad received line: #{hop}" + next + end + from = $+ if hop =~ /from\s+(\S+)|\((.*?)\)/ + by = $1 if hop =~ /by\s+(\S+\.\S+)/ + next unless now = Time.parse(whence).localtime + delta = now - @date + puts out([from, by, hop_date(now), hop_time(delta)]) + @date = now + end + end + + def hop_time(secs) + sign = secs < 0 ? -1 : 1 + days, secs = secs.abs.divmod(60 * 60 * 24) + hours,secs = secs.abs.divmod(60 * 60) + mins, secs = secs.abs.divmod(60) + rtn = "%3ds" % [secs * sign] + rtn << "%3dm" % [mins * sign] if mins != 0 + rtn << "%3dh" % [hours * sign] if hours != 0 + rtn << "%3dd" % [days * sign] if days != 0 + rtn + end +end + +$/ = "" +mail = MailHopDelta.new(ARGF.gets).puts_hops + + +# @@PLEAC@@_4.0 +single_level = [ "this", "that", "the", "other" ] + +# Ruby directly supports nested arrays +double_level = [ "this", "that", [ "the", "other" ] ] +still_single_level = [ "this", "that", [ "the", "other" ] ].flatten + + +# @@PLEAC@@_4.1 +a = [ "quick", "brown", "fox" ] +a = %w(Why are you teasing me?) + +lines = <<"END_OF_HERE_DOC".gsub(/^\s*(.+)/, '\1') + The boy stood on the burning deck, + It was as hot as glass. +END_OF_HERE_DOC + +bigarray = IO.readlines("mydatafile").collect { |l| l.chomp } + +name = "Gandalf" +banner = %Q(Speak, #{name}, and welcome!) + +host_info = `host #{his_host}` + +%x(ps #{$$}) + +banner = 'Costs only $4.95'.split(' ') + +rax = %w! ( ) < > { } [ ] ! + + +# @@PLEAC@@_4.2 +def commify_series(arr) + return '' if not arr + case arr.size + when 0 then '' + when 1 then arr[0] + when 2 then arr.join(' and ') + else arr[0..-2].join(', ') + ', and ' + arr[-1] + end +end + +array = [ "red", "yellow", "green" ] + +print "I have ", array, " marbles\n" +# -> I have redyellowgreen marbles + +# But unlike Perl: +print "I have #{array} marbles\n" +# -> I have redyellowgreen marbles +# So, needs: +print "I have #{array.join(' ')} marbles\n" +# -> I have red yellow green marbles + +#!/usr/bin/ruby +# communify_series - show proper comma insertion in list output + +def commify_series(arr) + return '' if not arr + sepchar = arr.find { |p| p =~ /,/ } ? '; ' : ', ' + case arr.size + when 0 then '' + when 1 then arr[0] + when 2 then arr.join(' and ') + else arr[0..-2].join(sepchar) + sepchar + 'and ' + arr[-1] + end +end + +lists = [ + [ 'just one thing' ], + %w(Mutt Jeff), + %w(Peter Paul Mary), + [ 'To our parents', 'Mother Theresa', 'God' ], + [ 'pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna' ], + [ 'recycle tired, old phrases', 'ponder big, happy thoughts' ], + [ 'recycle tired, old phrases', + 'ponder big, happy thoughts', + 'sleep and dream peacefully' ], +] + +for list in lists do + puts "The list is: #{commify_series(list)}." +end + + +# @@PLEAC@@_4.3 +# (note: AFAIK Ruby doesn't allow gory change of Array length) +# grow the array by assigning nil to past the end of array +ary[new_size-1] = nil +# shrink the array by slicing it down +ary.slice!(new_size..-1) +# init the array with given size +Array.new(number_of_elems) +# assign to an element past the original end enlarges the array +ary[index_new_last_elem] = value + +def what_about_that_array(a) + print "The array now has ", a.size, " elements.\n" + # Index of last element is not really interesting in Ruby + print "Element #3 is `#{a[3]}'.\n" +end +people = %w(Crosby Stills Nash Young) +what_about_that_array(people) + + +# @@PLEAC@@_4.4 +# OO style +bad_users.each { |user| + complain(user) +} +# or, functional style +for user in bad_users + complain(user) +end + +for var in ENV.keys.sort + puts "#{var}=#{ENV[var]}" +end + +for user in all_users + disk_space = get_usage(user) + if (disk_space > MAX_QUOTA) + complain(user) + end +end + +for l in IO.popen("who").readlines + print l if l =~ /^gc/ +end + +# we can mimic the obfuscated Perl way +while fh.gets # $_ is set to the line just read + chomp # $_ has a trailing \n removed, if it had one + split.each { |w| # $_ is split on whitespace + # but $_ is not set to each chunk as in Perl + print w.reverse + } +end +# ...or use a cleaner way +for l in fh.readlines + l.chomp.split.each { |w| print w.reverse } +end + +# same drawback as in problem 1.4, we can't mutate a Numeric... +array.collect! { |v| v - 1 } + +a = [ .5, 3 ]; b = [ 0, 1 ] +for ary in [ a, b ] + ary.collect! { |v| v * 7 } +end +puts "#{a.join(' ')} #{b.join(' ')}" + +# we can mutate Strings, cool; we need a trick for the scalar +for ary in [ [ scalar ], array, hash.values ] + ary.each { |v| v.strip! } # String#strip rules :) +end + + +# @@PLEAC@@_4.5 +# not relevant in Ruby since we have always references +for item in array + # do somethingh with item +end + + +# @@PLEAC@@_4.6 +unique = list.uniq + +# generate a list of users logged in, removing duplicates +users = `who`.collect { |l| l =~ /(\w+)/; $1 }.sort.uniq +puts("users logged in: #{commify_series(users)}") # see 4.2 for commify_series + + +# @@PLEAC@@_4.7 +a - b +# [ 1, 1, 2, 2, 3, 3, 3, 4, 5 ] - [ 1, 2, 4 ] -> [3, 5] + + +# @@PLEAC@@_4.8 +union = a | b +intersection = a & b +difference = a - b + + +# @@PLEAC@@_4.9 +array1.concat(array2) +# if you will assign to another object, better use: +new_ary = array1 + array2 + +members = [ "Time", "Flies" ] +initiates = [ "An", "Arrow" ] +members += initiates + +members = [ "Time", "Flies" ] +initiates = [ "An", "Arrow" ] +members[2,0] = [ "Like", initiates ].flatten + +members[0] = "Fruit" +members[3,2] = "A", "Banana" + + +# @@PLEAC@@_4.10 +reversed = ary.reverse + +ary.reverse_each { |e| + # do something with e +} + +descending = ary.sort.reverse +descending = ary.sort { |a,b| b <=> a } + + +# @@PLEAC@@_4.11 +# remove n elements from front of ary (shift n) +front = ary.slice!(0, n) + +# remove n elements from the end of ary (pop n) +end_ = ary.slice!(-n .. -1) + +# let's extend the Array class, to make that useful +class Array + def shift2() + slice!(0 .. 1) # more symetric with pop2... + end + def pop2() + slice!(-2 .. -1) + end +end + +friends = %w(Peter Paul Mary Jim Tim) +this, that = friends.shift2 + +beverages = %w(Dew Jolt Cola Sprite Fresca) +pair = beverages.pop2 + + +# @@PLEAC@@_4.12 +# use Enumerable#detect (or the synonym Enumerable#find) +highest_eng = employees.detect { |emp| emp.category == 'engineer' } + + +# @@PLEAC@@_4.13 +# use Enumerable#select (or the synonym Enumerable#find_all) +bigs = nums.select { |i| i > 1_000_000 } +pigs = users.keys.select { |k| users[k] > 1e7 } + +matching = `who`.select { |u| u =~ /^gnat / } + +engineers = employees.select { |e| e.position == 'Engineer' } + +secondary_assistance = applicants.select { |a| + a.income >= 26_000 && a.income < 30_000 +} + + +# @@PLEAC@@_4.14 +# normally you would have an array of Numeric (Float or +# Fixnum or Bignum), so you would use: +sorted = unsorted.sort +# if you have strings representing Integers or Floats +# you may specify another sort method: +sorted = unsorted.sort { |a,b| a.to_f <=> b.to_f } + +# let's use the list of my own PID's +`ps ux`.split("\n")[1..-1]. + select { |i| i =~ /^#{ENV['USER']}/ }. + collect { |i| i.split[1] }. + sort { |a,b| a.to_i <=> b.to_i }.each { |i| puts i } +puts "Select a process ID to kill:" +pid = gets.chomp +raise "Exiting ... \n" unless pid && pid =~ /^\d+$/ +Process.kill('TERM', pid.to_i) +sleep 2 +Process.kill('KILL', pid.to_i) + +descending = unsorted.sort { |a,b| b.to_f <=> a.to_f } + + +# @@PLEAC@@_4.15 +ordered = unordered.sort { |a,b| compare(a,b) } + +precomputed = unordered.collect { |e| [compute, e] } +ordered_precomputed = precomputed.sort { |a,b| a[0] <=> b[0] } +ordered = ordered_precomputed.collect { |e| e[1] } + +ordered = unordered.collect { |e| [compute, e] }. + sort { |a,b| a[0] <=> b[0] }. + collect { |e| e[1] } + +for employee in employees.sort { |a,b| a.name <=> b.name } + print employee.name, " earns \$ ", employee.salary, "\n" +end + +# Beware! `0' is true in Ruby. +# For chaining comparisons, you may use Numeric#nonzero?, which +# returns num if num is not zero, nil otherwise +sorted = employees.sort { |a,b| (a.name <=> b.name).nonzero? || b.age <=> a.age } + +users = [] +# getpwent is not wrapped in Ruby... let's fallback +IO.readlines('/etc/passwd').each { |u| users << u.split(':') } +users.sort! { |a,b| a[0] <=> b[0] } +for user in users + puts user[0] +end + +sorted = names.sort { |a,b| a[1, 1] <=> b[1, 1] } +sorted = strings.sort { |a,b| a.length <=> b.length } + +# let's show only the compact version +ordered = strings.collect { |e| [e.length, e] }. + sort { |a,b| a[0] <=> b[0] }. + collect { |e| e[1] } + +ordered = strings.collect { |e| [/\d+/.match(e)[0].to_i, e] }. + sort { |a,b| a[0] <=> b[0] }. + collect { |e| e[1] } + +print `cat /etc/passwd`.collect { |e| [e, e.split(':').indexes(3,2,0)].flatten }. + sort { |a,b| (a[1] <=> b[1]).nonzero? || (a[2] <=> b[2]).nonzero? || a[3] <=> b[3] }. + collect { |e| e[0] } + + +# @@PLEAC@@_4.16 +circular.unshift(circular.pop) # the last shall be first +circular.push(circular.shift) # and vice versa + +def grab_and_rotate(l) + l.push(ret = l.shift) + ret +end + +processes = [1, 2, 3, 4, 5] +while (1) + process = grab_and_rotate(processes) + puts "Handling process #{process}" + sleep 1 +end + + +# @@PLEAC@@_4.17 +def fisher_yates_shuffle(a) + (a.size-1).downto(1) { |i| + j = rand(i+1) + a[i], a[j] = a[j], a[i] if i != j + } +end + +def naive_shuffle(a) + for i in 0...a.size + j = rand(a.size) + a[i], a[j] = a[j], a[i] + end +end + + +# @@PLEAC@@_4.18 +#!/usr/bin/env ruby +# example 4-2 words +# words - gather lines, present in colums + +# class to encapsulate the word formatting from the input +class WordFormatter + def initialize(cols) + @cols = cols + end + + # helper to return the length of the longest word in the wordlist + def maxlen(wordlist) + max = 1 + for word in wordlist + if word.length > max + max = word.length + end + end + max + end + + # process the wordlist and print it formmated into columns + def output(wordlist) + collen = maxlen(wordlist) + 1 + columns = @cols / collen + columns = 1 if columns == 0 + rows = (wordlist.length + columns - 1) / columns + # now process each item, picking out proper piece for this position + 0.upto(rows * columns - 1) { |item| + target = (item % columns) * rows + (item / columns) + eol = ((item+1) % columns == 0) + piece = wordlist[target] || "" + piece = piece.ljust(collen) unless eol + print piece + puts if eol + } + # no need to finish it up, because eol is always true for the last element + end +end + +# get nr of chars that fit in window or console, see PLEAC 15.4 +# not portable -- linux only (?) +def getWinCharWidth() + buf = "\0" * 8 + $stdout.ioctl(0x5413, buf) + ws_row, ws_col, ws_xpixel, ws_ypixel = buf.unpack("$4") + ws_col || 80 +rescue + 80 +end + +# main program +cols = getWinCharWidth() +formatter = WordFormatter.new(cols) +words = readlines() +words.collect! { |line| + line.chomp +} +formatter.output(words) + + +# @@PLEAC@@_4.19 +# In ruby, Fixnum's are automatically converted to Bignum's when +# needed, so there is no need for an extra module +def factorial(n) + s = 1 + while n > 0 + s *= n + n -= 1 + end + s +end + +puts factorial(500) + +#--------------------------------------------------------- +# Example 4-3. tsc-permute +# tsc_permute: permute each word of input +def permute(items, perms) + unless items.length > 0 + puts perms.join(" ") + else + for i in items + newitems = items.dup + newperms = perms.dup + newperms.unshift(newitems.delete(i)) + permute(newitems, newperms) + end + end +end +# In ruby the main program must be after all definitions it is using +permute(ARGV, []) + +#--------------------------------------------------------- +# mjd_permute: permute each word of input + +def factorial(n) + s = 1 + while n > 0 + s *= n + n -= 1 + end + s +end + +# we use a class with a class variable store the private cache +# for the results of the factorial function. +class Factorial + @@fact = [ 1 ] + def Factorial.compute(n) + if @@fact[n] + @@fact[n] + else + @@fact[n] = n * Factorial.compute(n - 1) + end + end +end + +#--------------------------------------------------------- +# Example 4-4- mjd-permute +# n2pat(n, len): produce the N-th pattern of length len + +# We must use a lower case letter as parameter N, otherwise it is +# handled as constant Length is the length of the resulting +# array, not the index of the last element (length -1) like in +# the perl example. +def n2pat(n, length) + pat = [] + i = 1 + while i <= length + pat.push(n % i) + n /= i + i += 1 + end + pat +end + +# pat2perm(pat): turn pattern returned by n2pat() into +# permutation of integers. +def pat2perm(pat) + source = (0 .. pat.length - 1).to_a + perm = [] + perm.push(source.slice!(pat.pop)) while pat.length > 0 + perm +end + +def n2perm(n, len) + pat2perm(n2pat(n,len)) +end + +# In ruby the main program must be after all definitions +while gets + data = split + # the perl solution has used $#data, which is length-1 + num_permutations = Factorial.compute(data.length()) + 0.upto(num_permutations - 1) do |i| + # in ruby we can not use an array as selector for an array + # but by exchanging the two arrays, we can use the collect method + # which returns an array with the result of all block invocations + permutation = n2perm(i, data.length).collect { + |j| data[j] + } + puts permutation.join(" ") + end +end + + +# @@PLEAC@@_5.0 +age = { "Nat", 24, + "Jules", 25, + "Josh", 17 } + +age["Nat"] = 24 +age["Jules"] = 25 +age["Josh"] = 17 + +food_color = { + "Apple" => "red", + "Banana" => "yellow", + "Lemon" => "yellow", + "Carrot" => "orange" + } + +# In Ruby, you cannot avoid the double or simple quoting +# while manipulatin hashes + + +# @@PLEAC@@_5.1 +hash[key] = value + +food_color["Raspberry"] = "pink" +puts "Known foods:", food_color.keys + + +# @@PLEAC@@_5.2 +# does hash have a value for key ? +if (hash.has_key?(key)) + # it exists +else + # it doesn't +end + +[ "Banana", "Martini" ].each { |name| + print name, " is a ", food_color.has_key?(name) ? "food" : "drink", "\n" +} + +age = {} +age['Toddler'] = 3 +age['Unborn'] = 0 +age['Phantasm'] = nil + +for thing in ['Toddler', 'Unborn', 'Phantasm', 'Relic'] + print "#{thing}: " + print "Has-key " if age.has_key?(thing) + print "True " if age[thing] + print "Nonzero " if age[thing] && age[thing].nonzero? + print "\n" +end + +#=> +# Toddler: Has-key True Nonzero +# Unborn: Has-key True +# Phantasm: Has-key +# Relic: + +# You use Hash#has_key? when you use Perl's exists -> it checks +# for existence of a key in a hash. +# All Numeric are "True" in ruby, so the test doesn't have the +# same semantics as in Perl; you would use Numeric#nonzero? to +# achieve the same semantics (false if 0, true otherwise). + + +# @@PLEAC@@_5.3 +food_color.delete("Banana") + + +# @@PLEAC@@_5.4 +hash.each { |key, value| + # do something with key and value +} + +hash.each_key { |key| + # do something with key +} + +food_color.each { |food, color| + puts "#{food} is #{color}" +} + +food_color.each_key { |food| + puts "#{food} is #{food_color[food]}" +} + +# IMO this demonstrates that OO style is by far more readable +food_color.keys.sort.each { |food| + puts "#{food} is #{food_color[food]}." +} + +#----------------------------- +#!/usr/bin/ruby +# countfrom - count number of messages from each sender + +# Default value is 0 +from = Hash.new(0) +while gets + /^From: (.*)/ and from[$1] += 1 +end + +# More useful to sort by number of received mail by person +from.sort {|a,b| b[1]<=>a[1]}.each { |v| + puts "#{v[1]}: #{v[0]}" +} +#----------------------------- + + +# @@PLEAC@@_5.5 +# You may use the built-in 'inspect' method this way: +p hash + +# Or do it the Cookbook way: +hash.each { |k,v| puts "#{k} => #{v}" } + +# Sorted by keys +hash.sort.each { |e| puts "#{e[0]} => #{e[1]}" } +# Sorted by values +hash.sort{|a,b| a[1]<=>b[1]}.each { |e| puts "#{e[0]} => #{e[1]}" } + + +# @@PLEAC@@_5.7 +ttys = Hash.new +for i in `who` + user, tty = i.split + (ttys[user] ||= []) << tty # see problems_ruby for more infos +end +ttys.keys.sort.each { |k| + puts "#{k}: #{commify_series(ttys[k])}" # from 4.2 +} + + +# @@PLEAC@@_5.8 +surname = { "Mickey" => "Mantle", "Babe" => "Ruth" } +puts surname.index("Mantle") + +# If you really needed to 'invert' the whole hash, use Hash#invert + +#----------------------------- +#!/usr/bin/ruby -w +# foodfind - find match for food or color + +given = ARGV.shift or raise "usage: foodfind food_or_color" + +color = { + "Apple" => "red", + "Banana" => "yellow", + "Lemon" => "yellow", + "Carrot" => "orange", +} + +if (color.has_key?(given)) + puts "#{given} is a food with color #{color[given]}." +end +if (color.has_value?(given)) + puts "#{color.index(given)} is a food with color #{given}." +end +#----------------------------- + + +# @@PLEAC@@_5.9 +# Sorted by keys (Hash#sort gives an Array of pairs made of each key,value) +food_color.sort.each { |f| + puts "#{f[0]} is #{f[1]}." +} + +# Sorted by values +food_color.sort { |a,b| a[1] <=> b[1] }.each { |f| + puts "#{f[0]} is #{f[1]}." +} + +# Sorted by length of values +food_color.sort { |a,b| a[1].length <=> b[1].length }.each { |f| + puts "#{f[0]} is #{f[1]}." +} + + +# @@PLEAC@@_5.10 +merged = a.clone.update(b) # because Hash#update changes object in place + +drink_color = { "Galliano" => "yellow", "Mai Tai" => "blue" } +ingested_color = drink_color.clone.update(food_color) + +substance_color = {} +for i in [ food_color, drink_color ] + i.each_key { |k| + if substance_color.has_key?(k) + puts "Warning: #{k} seen twice. Using the first definition." + next + end + substance_color[k] = 1 + } +end + + +# @@PLEAC@@_5.11 +common = hash1.keys & hash2.keys + +this_not_that = hash1.keys - hash2.keys + + +# @@PLEAC@@_5.12 +# no problem here, Ruby handles any kind of object for key-ing +# (it takes Object#hash, which defaults to Object#id) + + +# @@PLEAC@@_5.13 +# AFAIK, not possible in Ruby + + +# @@PLEAC@@_5.14 +# Be careful, the following is possible only because Fixnum objects are +# special (documentation says: there is effectively only one Fixnum object +# instance for any given integer value). +count = Hash.new(0) +array.each { |e| + count[e] += 1 +} + + +# @@PLEAC@@_5.15 +father = { + "Cain" , "Adam", + "Abel" , "Adam", + "Seth" , "Adam", + "Enoch" , "Cain", + "Irad" , "Enoch", + "Mehujael" , "Irad", + "Methusael" , "Mehujael", + "Lamech" , "Methusael", + "Jabal" , "Lamech", + "Jubal" , "Lamech", + "Tubalcain" , "Lamech", + "Enos" , "Seth", +} + +while gets + chomp + begin + print $_, " " + end while $_ = father[$_] + puts +end + +children = {} +father.each { |k,v| + (children[v] ||= []) << k +} +while gets + chomp + puts "#{$_} begat #{(children[$_] || ['Nobody']).join(', ')}.\n" +end + +includes = {} +files.each { |f| + begin + for l in IO.readlines(f) + next unless l =~ /^\s*#\s*include\s*<([^>]+)>/ + (includes[$1] ||= []) << f + end + rescue SystemCallError + $stderr.puts "#$! (skipping)" + end +} + +include_free = includes.values.flatten.uniq - includes.keys + + +# @@PLEAC@@_5.16 +# dutree - print sorted intented rendition of du output +#% dutree +#% dutree /usr +#% dutree -a +#% dutree -a /bin + +# The DuNode class collects all information about a directory, +# and provides some convenience methods +class DuNode + + attr_reader :name + attr_accessor :size + attr_accessor :kids + + def initialize(name) + @name = name + @kids = [] + @size = 0 + end + + # support for sorting nodes with side + def size_compare(node2) + @size <=> node2.size + end + + def basename + @name.sub(/.*\//, "") + end + + #returns substring before last "/", nil if not there + def parent + p = @name.sub(/\/[^\/]+$/,"") + if p == @name + nil + else + p + end + end + +end + +# The DuTree does the acdtual work of +# getting the input, parsing it, builging up a tree +# and format it for output +class Dutree + + attr_reader :topdir + + def initialize + @nodes = Hash.new + @dirsizes = Hash.new(0) + @kids = Hash.new([]) + end + + # get a node by name, create it if it does not exist yet + def get_create_node(name) + if @nodes.has_key?(name) + @nodes[name] + else + node = DuNode.new(name) + @nodes[name] = node + node + end + end + + # run du, read in input, save sizes and kids + # stores last directory read in instance variable topdir + def input(arguments) + name = "" + cmd = "du " + arguments.join(" ") + IO.popen(cmd) { |pipe| + pipe.each { |line| + size, name = line.chomp.split(/\s+/, 2) + node = get_create_node(name) + node.size = size.to_i + @nodes[name] = node + parent = node.parent + if parent + get_create_node(parent).kids.push(node) + end + } + } + @topdir = @nodes[name] + end + + # figure out how much is taken in each directory + # that isn't stored in the subdirectories. Add a new + # fake kid called "." containing that much. + def get_dots(node) + cursize = node.size + for kid in node.kids + cursize -= kid.size + get_dots(kid) + end + if node.size != cursize + newnode = get_create_node(node.name + "/.") + newnode.size = cursize + node.kids.push(newnode) + end + end + + # recursively output everything + # passing padding and number width as well + # on recursive calls + def output(node, prefix="", width=0) + line = sprintf("%#{width}d %s", node.size, node.basename) + puts(prefix + line) + prefix += line.sub(/\d /, "| ") + prefix.gsub!(/[^|]/, " ") + if node.kids.length > 0 # not a bachelor node + kids = node.kids + kids.sort! { |a,b| + b.size_compare(a) + } + width = kids[0].size.to_s.length + for kid in kids + output(kid, prefix, width) + end + end + end + +end + +tree = Dutree.new +tree.input(ARGV) +tree.get_dots(tree.topdir) +tree.output(tree.topdir) + + +# @@PLEAC@@_6.0 +# The verbose version are match, sub, gsub, sub! and gsub!; +# pattern needs to be a Regexp object; it yields a MatchData +# object. +pattern.match(string) +string.sub(pattern, replacement) +string.gsub(pattern, replacement) +# As usual in Ruby, sub! does the same as sub but also modifies +# the object, the same for gsub!/gsub. + +# Sugared syntax yields the position of the match (or nil if no +# match). Note that the object at the right of the operator needs +# not to be a Regexp object (it can be a String). The "dont +# match" operator yields true or false. +meadow =~ /sheep/ # position of the match, nil if no match +meadow !~ /sheep/ # true if doesn't match, false if it does +# There is no sugared version for the substitution + +meadow =~ /\bovines?\b/i and print "Here be sheep!" + +string = "good food" +string.sub!(/o*/, 'e') + +# % echo ababacaca | ruby -ne 'puts $& if /(a|ba|b)+(a|ac)+/' +# ababa + +# The "global" (or "multiple") match is handled by String#scan +scan (/(\d+)/) { + puts "Found number #{$1}" +} + +# String#scan yields an Array if not used with a block +numbers = scan(/\d+/) + +digits = "123456789" +nonlap = digits.scan(/(\d\d\d)/) +yeslap = digits.scan(/(?=(\d\d\d))/) +puts "Non-overlapping: #{nonlap.join(' ')}" +puts "Overlapping: #{yeslap.join(' ')}"; +# Non-overlapping: 123 456 789 +# Overlapping: 123 234 345 456 567 678 789 + +string = "And little lambs eat ivy" +string =~ /l[^s]*s/ +puts "(#$`) (#$&) (#$')" +# (And ) (little lambs) ( eat ivy) + + +# @@PLEAC@@_6.1 +# Ruby doesn't have the same problem: +dst = src.sub('this', 'that') + +progname = $0.sub('^.*/', '') + +bindirs = %w(/usr/bin /bin /usr/local/bin) +libdirs = bindirs.map { |l| l.sub('bin', 'lib') } + + +# @@PLEAC@@_6.3 +/\S+/ # as many non-whitespace bytes as possible +/[A-Za-z'-]+/ # as many letters, apostrophes, and hyphens + +/\b([A-Za-z]+)\b/ # usually best +/\s([A-Za-z]+)\s/ # fails at ends or w/ punctuation + + +# @@PLEAC@@_6.4 +require 'socket' +str = 'www.ruby-lang.org and www.rubygarden.org' +re = / + ( # capture the hostname in $1 + (?: # these parens for grouping only + (?! [-_] ) # lookahead for neither underscore nor dash + [\w-] + # hostname component + \. # and the domain dot + ) + # now repeat that whole thing a bunch of times + [A-Za-z] # next must be a letter + [\w-] + # now trailing domain part + ) # end of $1 capture + /x # /x for nice formatting + +str.gsub! re do # pass a block to execute replacement + host = TCPsocket.gethostbyname($1) + "#{$1} [#{host[3]}]" +end + +puts str +#----------------------------- +# to match whitespace or #-characters in an extended re you need to escape +# them. + +foo = 42 +str = 'blah #foo# blah' +str.gsub! %r/ # replace + \# # a pound sign + (\w+) # the variable name + \# # another pound sign + /x do + eval $1 # with the value of a local variable + end +puts str # => blah 42 blah + + +# @@PLEAC@@_6.5 +# The 'g' modifier doesn't exist in Ruby, a regexp can't be used +# directly in a while loop; instead, use String#scan { |match| .. } +fish = 'One fish two fish red fish blue fish' +WANT = 3 +count = 0 +fish.scan(/(\w+)\s+fish\b/i) { + if (count += 1) == WANT + puts "The third fish is a #{$1} one." + end +} + +if fish =~ /(?:\w+\s+fish\s+){2}(\w+)\s+fish/i + puts "The third fish is a #{$1} one." +end + +pond = 'One fish two fish red fish blue fish' +# String#scan without a block gives an array of matches, each match +# being an array of all the specified groups +colors = pond.scan(/(\w+)\s+fish\b/i).flatten # get all matches +color = colors[2] # then the one we want +# or without a temporary array +color = pond.scan(/(\w+)\s+fish\b/i).flatten[2] # just grab element 3 +puts "The third fish in the pond is #{color}." + +count = 0 +fishes = 'One fish two fish red fish blue fish' +evens = fishes.scan(/(\w+)\s+fish\b/i).select { (count+=1) % 2 == 0 } +print "Even numbered fish are #{evens.join(' ')}." + +count = 0 +fishes.gsub(/ + \b # makes next \w more efficient + ( \w+ ) # this is what we\'ll be changing + ( + \s+ fish \b + ) + /x) { + if (count += 1) == 4 + 'sushi' + $2 + else + $1 + $2 + end +} + +pond = 'One fish two fish red fish blue fish swim here.' +puts "Last fish is #{pond.scan(/\b(\w+)\s+fish\b/i).flatten[-1]}" + +/ + A # find some pattern A + (?! # mustn\'t be able to find + .* # something + A # and A + ) + $ # through the end of the string +/x + +# The "s" perl modifier is "m" in Ruby (not very nice since there is +# also an "m" in perl..) +pond = "One fish two fish red fish blue fish swim here." +if (pond =~ / + \b ( \w+) \s+ fish \b + (?! .* \b fish \b ) + /mix) + puts "Last fish is #{$1}." +else + puts "Failed!" +end + + +# @@PLEAC@@_6.6 +#----------------------------- +#!/usr/bin/ruby -w +# killtags - very bad html killer +$/ = nil; # each read is whole file +while file = gets() do + file.gsub!(/<.*?>/m,''); # strip tags (terribly) + puts file # print file to STDOUT +end +#----------------------------- +#!/usr/bin/ruby -w +#headerfy - change certain chapter headers to html +$/ = '' +while file = gets() do + pattern = / + \A # start of record + ( # capture in $1 + Chapter # text string + \s+ # mandatory whitespace + \d+ # decimal number + \s* # optional whitespace + : # a real colon + . * # anything not a newline till end of line + ) + /x + puts file.gsub(pattern,'<H1>\1</H1>') +end +#----------------------------- +#% ruby -00pe "gsub!(/\A(Chapter\s+\d+\s*:.*)/,'<H1>\1</H1>')" datafile + +#!/usr/bin/ruby -w +#----------------------------- +for file in ARGV + file = File.open(ARGV.shift) + while file.gets('') do # each read is a paragraph + print "chunk #{$.} in $ARGV has <<#{$1}>>\n" while /^START(.*?)^END/m + end # /m activates the multiline mode +end +#----------------------------- + +# @@PLEAC@@_6.7 +#----------------------------- +$/ = nil; +file = File.open("datafile") +chunks = file.gets.split(/pattern/) +#----------------------------- +# .Ch, .Se and .Ss divide chunks of STDIN +chunks = gets(nil).split(/^\.(Ch|Se|Ss)$/) +print "I read #{chunks.size} chunks.\n" +#----------------------------- + + +# @@PLEAC@@_6.8 +while gets + if ~/BEGIN/ .. ~/END/ + # line falls between BEGIN and END inclusive + end +end + +while gets + if ($. == firstnum) .. ($. == lastnum) + # operate between firstnum and lastnum line number + end +end + +# in ruby versions prior to 1.8, the above two conditional +# expressions could be shortened to: +# if /BEGIN/ .. /END/ +# and +# if firstnum .. lastnum +# but these now only work this way from the command line + +#----------------------------- + +while gets + if ~/BEGIN/ ... ~/END/ + # line falls between BEGIN and END on different lines + end +end + +while gets + if ($. == first) ... ($. == last) + # operate between first and last line number on different lines + end +end + +#----------------------------- +# command-line to print lines 15 through 17 inclusive (see below) +ruby -ne 'print if 15 .. 17' datafile + +# print out all <XMP> .. </XMP> displays from HTML doc +while gets + print if ~%r#<XMP>#i .. ~%r#</XMP>#i; +end + +# same, but as shell command +# ruby -ne 'print if %r#<XMP>#i .. %r#</XMP>#i' document.html +#----------------------------- +# ruby -ne 'BEGIN { $top=3; $bottom=5 }; \ +# print if $top .. $bottom' /etc/passwd # FAILS +# ruby -ne 'BEGIN { $top=3; $bottom=5 }; \ +# print if $. == $top .. $. == $bottom' /etc/passwd # works +# ruby -ne 'print if 3 .. 5' /etc/passwd # also works +#----------------------------- +print if ~/begin/ .. ~/end/; +print if ~/begin/ ... ~/end/; +#----------------------------- +while gets + $in_header = $. == 1 .. ~/^$/ ? true : false + $in_body = ~/^$/ .. ARGF.eof ? true : false +end +#----------------------------- +seen = {} +ARGF.each do |line| + next unless line =~ /^From:?\s/i .. line =~ /^$/; + line.scan(%r/([^<>(),;\s]+\@[^<>(),;\s]+)/).each do |addr| + puts addr unless seen[addr] + seen[addr] ||= 1 + end +end + + +# @@PLEAC@@_6.9 +def glob2pat(globstr) + patmap = { + '*' => '.*', + '?' => '.', + '[' => '[', + ']' => ']', + } + globstr.gsub!(/(.)/) { |c| patmap[c] || Regexp::escape(c) } + '^' + globstr + '$' +end + + +# @@PLEAC@@_6.10 +# avoid interpolating patterns like this if the pattern +# isn't going to change: +pattern = ARGV.shift +ARGF.each do |line| + print line if line =~ /#{pattern}/ +end + +# the above creates a new regex each iteration. Instead, +# use the /o modifier so the regex is compiled only once + +pattern = ARGV.shift +ARGF.each do |line| + print line if line =~ /#{pattern}/o +end + +#----------------------------- + +#!/usr/bin/ruby +# popgrep1 - grep for abbreviations of places that say "pop" +# version 1: slow but obvious way +popstates = %w(CO ON MI WI MN) +ARGF.each do |line| + popstates.each do |state| + if line =~ /\b#{state}\b/ + print line + last + end + end +end + +#----------------------------- +#!/usr/bin/ruby +# popgrep2 - grep for abbreviations of places that say "pop" +# version 2: eval strings; fast but hard to quote +popstates = %w(CO ON MI WI MN) +code = "ARGF.each do |line|\n" +popstates.each do |state| + code += "\tif line =~ /\\b#{state}\\b/; print(line); next; end\n" +end +code += "end\n" +print "CODE IS\n---\n#{code}\n---\n" if false # turn on for debugging +eval code + +# CODE IS +# --- +# ARGF.each do |line| +# if line =~ /\bCO\b/; print(line); next; end +# if line =~ /\bON\b/; print(line); next; end +# if line =~ /\bMI\b/; print(line); next; end +# if line =~ /\bWI\b/; print(line); next; end +# if line =~ /\bMN\b/; print(line); next; end +# end +# +# --- + +## alternatively, the same idea as above but compiling +## to a case statement: (not in perlcookbook) +#!/usr/bin/ruby -w +# popgrep2.5 - grep for abbreviations of places that say "pop" +# version 2.5: eval strings; fast but hard to quote +popstates = %w(CO ON MI WI MN) +code = "ARGF.each do |line|\n case line\n" +popstates.each do |state| + code += " when /\\b#{state}\\b/ : print line\n" +end +code += " end\nend\n" +print "CODE IS\n---\n#{code}\n---\n" if false # turn on for debugging +eval code + +# CODE IS +# --- +# ARGF.each do |line| +# case line +# when /\bCO\b/ : print line +# when /\bON\b/ : print line +# when /\bMI\b/ : print line +# when /\bWI\b/ : print line +# when /\bMN\b/ : print line +# end +# end +# +# --- + +# Note: (above) Ruby 1.8+ allows the 'when EXP : EXPR' on one line +# with the colon separator. + +#----------------------------- +#!/usr/bin/ruby +# popgrep3 - grep for abbreviations of places that say "pop" +# version3: build a match_any function +popstates = %w(CO ON MI WI MN) +expr = popstates.map{|e|"line =~ /\\b#{e}\\b/"}.join('||') +eval "def match_any(line); #{expr};end" +ARGF.each do |line| + print line if match_any(line) +end +#----------------------------- + +## building a match_all function is a trivial +## substitution of && for || +## here is a generalized example: +#!/usr/bin/ruby -w +## grepauth - print lines that mention both foo and bar +class MultiMatch + def initialize(*patterns) + _any = build_match('||',patterns) + _all = build_match('&&',patterns) + eval "def match_any(line);#{_any};end\n" + eval "def match_all(line);#{_all};end\n" + end + def build_match(sym,args) + args.map{|e|"line =~ /#{e}/"}.join(sym) + end +end + +mm = MultiMatch.new('foo','bar') +ARGF.each do |line| + print line if mm.match_all(line) +end +#----------------------------- + +#!/usr/bin/ruby +# popgrep4 - grep for abbreviations of places that say "pop" +# version4: pretty fast, but simple: compile all re's first: +popstates = %w(CO ON MI WI MN) +popstates = popstates.map{|re| %r/\b#{re}\b/} +ARGF.each do |line| + popstates.each do |state_re| + if line =~ state_re + print line + break + end + end +end + +## speeds trials on the jargon file(412): 26006 lines, 1.3MB +## popgrep1 => 7.040s +## popgrep2 => 0.656s +## popgrep2.5 => 0.633s +## popgrep3 => 0.675s +## popgrep4 => 1.027s + +# unless speed is criticial, the technique in popgrep4 is a +# reasonable balance between speed and logical simplicity. + + +# @@PLEAC@@_6.11 +begin + print "Pattern? " + pat = $stdin.gets.chomp + Regexp.new(pat) +rescue + warn "Invalid Pattern" + retry +end + + +# @@PLEAC@@_6.13 +# uses the 'amatch' extension found on: +# http://raa.ruby-lang.org/project/amatch/ +require 'amatch' +matcher = Amatch.new('balast') +#$relative, $distance = 0, 1 +File.open('/usr/share/dict/words').each_line do |line| + print line if matcher.search(line) <= 1 +end +__END__ +#CODE +ballast +ballasts +balustrade +balustrades +blast +blasted +blaster +blasters +blasting +blasts + + +# @@PLEAC@@_6.14 +str.scan(/\G(\d)/).each do |token| + puts "found #{token}" +end +#----------------------------- +n = " 49 here" +n.gsub!(/\G /,'0') +puts n +#----------------------------- +str = "3,4,5,9,120" +str.scan(/\G,?(\d+)/).each do |num| + puts "Found number: #{num}" +end +#----------------------------- +# Ruby doesn't have the String.pos or a /c re modifier like Perl +# But it does have StringScanner in the standard library (strscn) +# which allows similar functionality: + +require 'strscan' +text = 'the year 1752 lost 10 days on the 3rd of September' +sc = StringScanner.new(text) +while sc.scan(/.*?(\d+)/) + print "found: #{sc[1]}\n" +end +if sc.scan(/\S+/) + puts "Found #{sc[0]} after last number" +end +#----------------------------- +# assuming continuing from above: +puts "The position in 'text' is: #{sc.pos}" +sc.pos = 30 +puts "The position in 'text' is: #{sc.pos}" + + +# @@PLEAC@@_6.15 +#----------------------------- +# greedy pattern +str.gsub!(/<.*>/m,'') # not good + +# non-greedy (minimal) pattern +str.gsub!(/<.*?>/m,'') # not great + + +#----------------------------- +#<b><i>this</i> and <i>that</i> are important</b> Oh, <b><i>me too!</i></b> +#----------------------------- +%r{ <b><i>(.*?)</i></b> }mx +#----------------------------- +%r/BEGIN((?:(?!BEGIN).)*)END/ +#----------------------------- +%r{ <b><i>( (?: (?!</b>|</i>). )* ) </i></b> }mx +#----------------------------- +%r{ <b><i>( (?: (?!</[ib]>). )* ) </i></b> }mx +#----------------------------- +%r{ + <b><i> + [^<]* # stuff not possibly bad, and not possibly the end. + (?: + # at this point, we can have '<' if not part of something bad + (?! </?[ib]> ) # what we can't have + < # okay, so match the '<' + [^<]* # and continue with more safe stuff + ) * + </i></b> + }mx + + +# @@PLEAC@@_6.16 +#----------------------------- +$/ = "" +ARGF.each do |para| + para.scan %r/ + \b # start at word boundary + (\S+) # find chunk of non-whitespace + \b # until a word boundary + ( + \s+ # followed by whitespace + \1 # and that same chunk again + \b # and a word boundary + ) + # one or more times + /xi do + puts "dup word '#{$1}' at paragraph #{$.}" + end +end +#----------------------------- +astr = 'nobody' +bstr = 'bodysnatcher' +if "#{astr} #{bstr}" =~ /^(\w+)(\w+) \2(\w+)$/ + print "#{$2} overlaps in #{$1}-#{$2}-#{$3}" +end +#----------------------------- +#!/usr/bin/ruby -w +# prime_pattern -- find prime factors of argument using patterns +ARGV << 180 +cap = 'o' * ARGV.shift +while cap =~ /^(oo+?)\1+$/ + print $1.size, " " + cap.gsub!(/#{$1}/,'o') +end +puts cap.size +#----------------------------- +#diophantine +# solve for 12x + 15y + 16z = 281, maximizing x +if ('o' * 281).match(/^(o*)\1{11}(o*)\2{14}(o*)\3{15}$/) + x, y, z = $1.size, $2.size, $3.size + puts "One solution is: x=#{x}; y=#{y}; z=#{z}" +else + puts "No solution." +end +# => One solution is: x=17; y=3; z=2 + +#----------------------------- +# using different quantifiers: +('o' * 281).match(/^(o+)\1{11}(o+)\2{14}(o+)\3{15}$/) +# => One solution is: x=17; y=3; z=2 + +('o' * 281).match(/^(o*?)\1{11}(o*)\2{14}(o*)\3{15}$/) +# => One solution is: x=0; y=7; z=11 + +('o' * 281).match(/^(o+?)\1{11}(o*)\2{14}(o*)\3{15}$/) +# => One solution is: x=1; y=3; z=14 + + +# @@PLEAC@@_6.17 +# alpha OR beta +%r/alpha|beta/ + +# alpha AND beta +%r/(?=.*alpha)(?=.*beta)/m + +# alpha AND beta, no overlap +%r/alpha.*beta|beta.*alpha/m + +# NOT beta +%r/^(?:(?!beta).)*$/m + +# NOT bad BUT good +%r/(?=(?:(?!BAD).)*$)GOOD/m +#----------------------------- + +if !(string =~ /pattern/) # ugly + something() +end + +if string !~ /pattern/ # preferred + something() +end + + +#----------------------------- +if string =~ /pat1/ && string =~ /pat2/ + something() +end +#----------------------------- +if string =~ /pat1/ || string =~ /pat2/ + something() +end +#----------------------------- +#!/usr/bin/ruby -w +# minigrep - trivial grep +pat = ARGV.shift +ARGF.each do |line| + print line if line =~ /#{pat}/o +end +#----------------------------- + "labelled" =~ /^(?=.*bell)(?=.*lab)/m +#----------------------------- +$string =~ /bell/ && $string =~ /lab/ +#----------------------------- +$murray_hill = "blah bell blah " +if $murray_hill =~ %r{ + ^ # start of string + (?= # zero-width lookahead + .* # any amount of intervening stuff + bell # the desired bell string + ) # rewind, since we were only looking + (?= # and do the same thing + .* # any amount of intervening stuff + lab # and the lab part + ) + }mx # /m means . can match newline + + print "Looks like Bell Labs might be in Murray Hill!\n"; +end +#----------------------------- +"labelled" =~ /(?:^.*bell.*lab)|(?:^.*lab.*bell)/ +#----------------------------- +$brand = "labelled"; +if $brand =~ %r{ + (?: # non-capturing grouper + ^ .*? # any amount of stuff at the front + bell # look for a bell + .*? # followed by any amount of anything + lab # look for a lab + ) # end grouper + | # otherwise, try the other direction + (?: # non-capturing grouper + ^ .*? # any amount of stuff at the front + lab # look for a lab + .*? # followed by any amount of anything + bell # followed by a bell + ) # end grouper + }mx # /m means . can match newline + print "Our brand has bell and lab separate.\n"; +end +#----------------------------- +$map =~ /^(?:(?!waldo).)*$/s +#----------------------------- +$map = "the great baldo" +if $map =~ %r{ + ^ # start of string + (?: # non-capturing grouper + (?! # look ahead negation + waldo # is he ahead of us now? + ) # is so, the negation failed + . # any character (cuzza /s) + ) * # repeat that grouping 0 or more + $ # through the end of the string + }mx # /m means . can match newline + print "There's no waldo here!\n"; +end +=begin + 7:15am up 206 days, 13:30, 4 users, load average: 1.04, 1.07, 1.04 + +USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT + +tchrist tty1 5:16pm 36days 24:43 0.03s xinit + +tchrist tty2 5:19pm 6days 0.43s 0.43s -tcsh + +tchrist ttyp0 chthon 7:58am 3days 23.44s 0.44s -tcsh + +gnat ttyS4 coprolith 2:01pm 13:36m 0.30s 0.30s -tcsh +=end +#% w | minigrep '^(?!.*ttyp).*tchrist' +#----------------------------- +%r{ + ^ # anchored to the start + (?! # zero-width look-ahead assertion + .* # any amount of anything (faster than .*?) + ttyp # the string you don't want to find + ) # end look-ahead negation; rewind to start + .* # any amount of anything (faster than .*?) + tchrist # now try to find Tom +}x +#----------------------------- +#% w | grep tchrist | grep -v ttyp +#----------------------------- +#% grep -i 'pattern' files +#% minigrep '(?i)pattern' files +#----------------------------- + + +# @@PLEAC@@_6.20 +ans = $stdin.gets.chomp +re = %r/^#{Regexp.quote(ans)}/ +case + when "SEND" =~ re : puts "Action is send" + when "STOP" =~ re : puts "Action is stop" + when "ABORT" =~ re : puts "Action is abort" + when "EDIT" =~ re : puts "Action is edit" +end +#----------------------------- +require 'abbrev' +table = Abbrev.abbrev %w-send stop abort edit- +loop do + print "Action: " + ans = $stdin.gets.chomp + puts "Action for #{ans} is #{table[ans.downcase]}" +end + + +#----------------------------- +# dummy values are defined for 'file', 'PAGER', and +# the 'invoke_editor' and 'deliver_message' methods +# do not do anything interesting in this example. +#!/usr/bin/ruby -w +require 'abbrev' + +file = 'pleac_ruby.data' +PAGER = 'less' + +def invoke_editor + puts "invoking editor" +end + +def deliver_message + puts "delivering message" +end + +actions = { + 'edit' => self.method(:invoke_editor), + 'send' => self.method(:deliver_message), + 'list' => proc {system(PAGER, file)}, + 'abort' => proc {puts "See ya!"; exit}, + "" => proc {puts "Unknown Command"} +} + +dtable = Abbrev.abbrev(actions.keys) +loop do + print "Action: " + ans = $stdin.gets.chomp.delete(" \t") + actions[ dtable[ans.downcase] || "" ].call +end + + +# @@PLEAC@@_6.19 +#----------------------------- +# basically, the Perl Cookbook categorizes this as an +# unsolvable problem ... +#----------------------------- +1 while addr.gsub!(/\([^()]*\)/,'') +#----------------------------- +Dear someuser@host.com, + +Please confirm the mail address you gave us Wed May 6 09:38:41 +MDT 1998 by replying to this message. Include the string +"Rumpelstiltskin" in that reply, but spelled in reverse; that is, +start with "Nik...". Once this is done, your confirmed address will +be entered into our records. + + +# @@PLEAC@@_6.21 +#----------------------------- +#% gunzip -c ~/mail/archive.gz | urlify > archive.urlified +#----------------------------- +#% urlify ~/mail/*.inbox > ~/allmail.urlified +#----------------------------- +#!/usr/bin/ruby -w +# urlify - wrap HTML links around URL-like constructs + +urls = '(https?|telnet|gopher|file|wais|ftp)'; +ltrs = '\w'; +gunk = '/#~:.?+=&%@!\-'; +punc = '.:?\-'; +any = "#{ltrs}#{gunk}#{punc}"; + +ARGF.each do |line| + line.gsub! %r/ + \b # start at word boundary + ( # begin $1 { + #{urls} : # need resource and a colon + [#{any}] +? # followed by on or more + # of any valid character, but + # be conservative and take only + # what you need to.... + ) # end $1 } + (?= # look-ahead non-consumptive assertion + [#{punc}]* # either 0 or more punctuation + [^#{any}] # followed by a non-url char + | # or else + $ # then end of the string + ) + /iox do + %Q|<A HREF="#{$1}">#{$1}</A>| + end + print line +end + + +# @@PLEAC@@_6.23 +%r/^m*(d?c{0,3}|c[dm])(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$/i +#----------------------------- +str.sub!(/(\S+)(\s+)(\S+)/, '\3\2\1') +#----------------------------- +%r/(\w+)\s*=\s*(.*)\s*$/ # keyword is $1, value is $2 +#----------------------------- +%r/.{80,}/ +#----------------------------- +%r|(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)| +#----------------------------- +str.gsub!(%r|/usr/bin|,'/usr/local/bin') +#----------------------------- +str.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/){ $1.hex.chr } +#----------------------------- +str.gsub!(%r{ + /\* # Match the opening delimiter + .*? # Match a minimal number of characters + \*/ # Match the closing delimiter +}xm,'') +#----------------------------- +str.sub!(/^\s+/, '') +str.sub!(/\s+$/, '') + +# but really, in Ruby we'd just do: +str.strip! +#----------------------------- +str.gsub!(/\\n/,"\n") +#----------------------------- +str.sub!(/^.*::/, '') +#----------------------------- +%r/^([01]?\d\d|2[0-4]\d|25[0-5])\.([01]?\d\d|2[0-4]\d|25[0-5])\. + ([01]?\d\d|2[0-4]\d|25[0-5])\.([01]?\d\d|2[0-4]\d|25[0-5])$/x +#----------------------------- +str.sub!(%r|^.*/|, '') +#----------------------------- +cols = ( (ENV['TERMCAP'] || " ") =~ /:co#(\d+):/ ) ? $1 : 80; +#----------------------------- +name = " #{$0} #{ARGV}".gsub(%r| /\S+/|, ' ') +#----------------------------- +require 'rbconfig' +include Config +raise "This isn't Linux" unless CONFIG['target_os'] =~ /linux/i; +#----------------------------- +str.gsub!(%r/\n\s+/, ' ') +#----------------------------- +nums = str.scan(/(\d+\.?\d*|\.\d+)/) +#----------------------------- +capwords = str.scan(%r/(\b[^\Wa-z0-9_]+\b)/) +#----------------------------- +lowords = str.scan(%r/(\b[^\WA-Z0-9_]+\b)/) +#----------------------------- +icwords = str.scan(%r/(\b[^\Wa-z0-9_][^\WA-Z0-9_]*\b)/) +#----------------------------- +links = str.scan(%r/<A[^>]+?HREF\s*=\s*["']?([^'" >]+?)[ '"]?>/mi) +#----------------------------- +initial = str =~ /^\S+\s+(\S)\S*\s+\S/ ? $1 : "" +#----------------------------- +str.gsub!(%r/"([^"]*)"/, %q-``\1''-) +#----------------------------- + +$/ = "" +sentences = [] +ARGF.each do |para| + para.gsub!(/\n/, ' ') + para.gsub!(/ {3,}/,' ') + sentences << para.scan(/(\S.*?[!?.])(?= |\Z)/) +end + +#----------------------------- +%r/(\d{4})-(\d\d)-(\d\d)/ # YYYY in $1, MM in $2, DD in $3 +#----------------------------- +%r/ ^ + (?: + 1 \s (?: \d\d\d \s)? # 1, or 1 and area code + | # ... or ... + \(\d\d\d\) \s # area code with parens + | # ... or ... + (?: \+\d\d?\d? \s)? # optional +country code + \d\d\d ([\s\-]) # and area code + ) + \d\d\d (\s|\1) # prefix (and area code separator) + \d\d\d\d # exchange + $ + /x +#----------------------------- +%r/\boh\s+my\s+gh?o(d(dess(es)?|s?)|odness|sh)\b/i +#----------------------------- +lines = [] +lines << $1 while input.sub!(/^([^\012\015]*)(\012\015?|\015\012?)/,'') + + +# @@PLEAC@@_7.0 +# An IO object being Enumerable, we can use 'each' directly on it +File.open("/usr/local/widgets/data").each { |line| + puts line if line =~ /blue/ +} + +logfile = File.new("/var/log/rubylog.txt", "w") +mysub($stdin, logfile) + +# The method IO#readline is similar to IO#gets +# but throws an exception when it reaches EOF +f = File.new("bla.txt") +begin + while (line = f.readline) + line.chomp + $stdout.print line if line =~ /blue/ + end +rescue EOFError + f.close +end + +while $stdin.gets # reads from STDIN + unless (/\d/) + $stderr.puts "No digit found." # writes to STDERR + end + puts "Read: #{$_}" # writes to STDOUT +end + +logfile = File.new("/tmp/log", "w") + +logfile.close + +# $defout (or its synonym '$>') is the destination of output +# for Kernel#print, Kernel#puts, and family functions +logfile = File.new("log.txt", "w") +old = $defout +$defout = logfile # switch to logfile for output +puts "Countdown initiated ..." +$defout = old # return to original output +puts "You have 30 seconds to reach minimum safety distance." + + +# @@PLEAC@@_7.1 +source = File.new(path, "r") # open file "path" for reading only +sink = File.new(path, "w") # open file "path" for writing only + +source = File.open(path, File::RDONLY) # open file "path" for reading only +sink = File.open(path, File::WRONLY) # open file "path" for writing only + +file = File.open(path, "r+") # open "path" for reading and writing +file = File.open(path, flags) # open "path" with the flags "flags" (see examples below for flags) + +# open file "path" read only +file = File.open(path, "r") +file = File.open(path, File::RDONLY) + +# open file "path" write only, create it if it does not exist +# truncate it to zero length if it exists +file = File.open(path, "w") +file = File.open(path, File::WRONLY|File::TRUNC|File::CREAT) +file = File.open(path, File::WRONLY|File::TRUNC|File::CREAT, 0666) # with permission 0666 + +# open file "path" write only, fails if file exists +file = File.open(path, File::WRONLY|File::EXCL|File::CREAT) +file = File.open(path, File::WRONLY|File::EXCL|File::CREAT, 0666) + +# open file "path" for appending +file = File.open(path, "a") +file = File.open(path, File::WRONLY|File::APPEND|File::CREAT) +file = File.open(path, File::WRONLY|File::APPEND|File::CREAT, 0666) + +# open file "path" for appending only when file exists +file = File.open(path, File::WRONLY|File::APPEND) + +# open file "path" for reading and writing +file = File.open(path, "r+") +file = File.open(path, File::RDWR) + +# open file for reading and writing, create a new file if it does not exist +file = File.open(path, File::RDWR|File::CREAT) +file = File.open(path, File::RDWR|File::CREAT, 0600) + +# open file "path" reading and writing, fails if file exists +file = File.open(path, File::RDWR|File::EXCL|File::CREAT) +file = File.open(path, File::RDWR|File::EXCL|File::CREAT, 0600) + + +# @@PLEAC@@_7.2 +# No problem with Ruby since the filename doesn't contain characters with +# special meaning; like Perl's sysopen +File.open(filename, 'r') + + +# @@PLEAC@@_7.3 +File.expand_path('~root/tmp') +#=> "/root/tmp" +File.expand_path('~rpcuser') +#=> "/var/lib/nfs" + +# To expand ~/.. it explicitely needs the environment variable HOME +File.expand_path('~/tmp') +#=> "/home/gc/tmp" + + +# @@PLEAC@@_7.4 +# The exception raised in Ruby reports the filename +File.open('afile') + + +# @@PLEAC@@_7.5 +# Standard Ruby distribution provides the following useful extension +require 'tempfile' +# With the Tempfile class, the file is automatically deleted on garbage +# collection, so you won't need to remove it, later on. +tf = Tempfile.new('tmp') # a name is required to create the filename + +# If you need to pass the filename to an external program you can use +# File#path, but don't forget to File#flush in order to flush anything +# living in some buffer somewhere. +tf.flush +system("/usr/bin/dowhatever #{tf.path}") + +fh = Tempfile.new('tmp') +fh.sync = true # autoflushes +10.times { |i| fh.puts i } +fh.rewind +puts 'Tmp file has: ', fh.readlines + + +# @@PLEAC@@_7.6 +while (DATA.gets) do + # process the line +end +__END__ +# your data goes here +# __DATA__ doesn't exist in Ruby + +#CODE +# get info about the script (size, date of last modification) +kilosize = DATA.stat.size / 1024 +last_modif = DATA.stat.mtime +puts "<P>Script size is #{kilosize}" +puts "<P>Last script update: #{last_modif}" +__END__ +# DO NOT REMOVE THE PRECEEDING LINE. +# Everything else in this file will be ignored. +#CODE + + +# @@PLEAC@@_7.7 +while line = gets do + # do something with line. +end + +# or +while gets do + # do something with $_ +end + +# or more rubyish +$stdin.each do |line| + # do stuff with line +end + + +# ARGF may makes this more easy +# this is skipped if ARGV.size==0 +ARGV.each do |filename| + # closing and exception handling are done by the block + open(filename) do |fd| + fd.each do |line| + # do stuff with line + end + end rescue abort("can't open %s" % filename) +end + +# globbing is done in the Dir module +ARGV = Dir["*.[Cch]"] if ARGV.empty? + +# note: optparse is the preferred way to handle this +if (ARGV[0] == '-c') + chop_first += 1 + ARGV.shift +end + + +# processing numerical options +if ARGV[0] =~ /^-(\d+)$/ + columns = $1 + ARGV.shift +end + +# again, better to use optparse: +require 'optparse' +nostdout = 0 +append = 0 +unbuffer = 0 +ignore_ints = 0 +ARGV.options do |opt| + opt.on('-n') { nostdout +=1 } + opt.on('-a') { append +=1 } + opt.on('-u') { unbuffer +=1 } + opt.on('-i') { ignore_ints +=1 } + opt.parse! +end or abort("usage: " + __FILE__ + " [-ainu] [filenames]") + +# no need to do undef $/, we have File.read +str = File.read(ARGV[0]) + +# again we have File.read +str = File.read(ARGV[0]) + +# not sure what this should do: +# I believe open the file, print filename, lineno and line: +ARGF.each_with_index do |line, idx| + print ARGF.filename, ":", idx, ";", line +end + +# print all the lines in every file passed via command line that contains login +ARGF.each do |line| + puts line if line =~ /login/ +end +# +# even this would fit +#%ruby -ne "print if /f/" 2.log +# + +ARGF.each { |l| puts l.downcase! } + +#------------------ +#!/usr/bin/ruby -p +# just like perl's -p +$_.downcase! +# + +# I don't know who should I trust. +# perl's version splits on \w+ while python's on \w. + +chunks = 0 + +File.read(ARGV[0]).split.each do |word| + next if word =~ /^#/ + break if ["__DATA__", "__END__"].member? word + chunks += 1 +end + +print "Found ", chunks, " chunks\n" + + +# @@PLEAC@@_7.8 +old = File.open(old_file) +new = File.open(new_file, "w") +while old.gets do + # change $_, then... + new.print $_ +end +old.close +new.close +File.rename(old_file, "old.orig") +File.rename(new_file, old_file) + +while old.gets do + if $. == 20 then # we are at the 20th line + new.puts "Extra line 1" + new.puts "Extra line 2" + end + new.print $_ +end + +while old.gets do + next if 20..30 # skip the 20th line to the 30th + # Ruby (and Perl) permit to write if 20..30 + # instead of if (20 <= $.) and ($. <= 30) + new.print $_ +end + + +# @@PLEAC@@_7.9 +#% ruby -i.orig -pe 'FILTER COMMAND' file1 file2 file3 ... +# +#----------------------------- +##!/usr/bin/ruby -i.orig -p +# filter commands go here +#----------------------------- + +#% ruby -pi.orig -e 'gsub!(/DATE/){Time.now)' + +# effectively becomes: +ARGV << 'I' +oldfile = "" +while gets + if ARGF.filename != oldfile + newfile = ARGF.filename + File.rename(newfile, newfile + ".orig") + $stdout = File.open(newfile,'w') + oldfile = newfile + end + gsub!(/DATE/){Time.now} + print +end +$stdout = STDOUT +#----------------------------- +#% ruby -i.old -pe 'gsub!(%r{\bhisvar\b}, 'hervar')' *.[Cchy] + +#----------------------------- +# set up to iterate over the *.c files in the current directory, +# editing in place and saving the old file with a .orig extension +$-i = '.orig' # set up -i mode +ARGV.replace(Dir['*.[Cchy]']) +while gets + if $. == 1 + print "This line should appear at the top of each file\n" + end + gsub!(/\b(p)earl\b/i, '\1erl') # Correct typos, preserving case + print + ARGF.close if ARGF.eof +end + + +# @@PLEAC@@_7.10 +File.open('itest', 'r+') do |f| # open file for update + lines = f.readlines # read into array of lines + lines.each do |it| # modify lines + it.gsub!(/foo/, 'QQQ') + end + f.pos = 0 # back to start + f.print lines # write out modified lines + f.truncate(f.pos) # truncate to new length +end # file is automatically closed +#----------------------------- +File.open('itest', 'r+') do |f| + out = "" + f.each do |line| + out << line.gsub(/DATE/) {Time.now} + end + f.pos = 0 + f.print out + f.truncate(f.pos) +end + +# @@PLEAC@@_7.11 +File.open('infile', 'r+') do |f| + f.flock File::LOCK_EX + # update file +end +#----------------------------- +File::LOCK_SH # shared lock (for reading) +File::LOCK_EX # exclusive lock (for writing) +File::LOCK_NB # non-blocking request +File::LOCK_UN # free lock +#----------------------------- +unless f.flock File::LOCK_EX | File::LOCK_NB + warn "can't get immediate lock: blocking ..." + f.flock File::LOCK_EX +end +#----------------------------- +File.open('numfile', File::RDWR|File::CREAT) do |f| + f.flock(File::LOCK_EX) + num = f.gets.to_i || 0 + f.pos = 0 + f.truncate 0 + f.puts num + 1q +end + + +# @@PLEAC@@_7.12 +output_handle.sync = true +# Please note that like in Perl, $stderr is already unbuffered +#----------------------------- +#!/usr/bin/ruby -w +# seeme - demo stdio output buffering +$stdout.sync = ARGV.size > 0 +print "Now you don't see it..." +sleep 2 +puts "now you do" +#----------------------------- +$stderr.sync = true +afile.sync = false +#----------------------------- +# assume 'remote_con' is an interactive socket handle, +# but 'disk_file' is a handle to a regular file. +remote_con.sync = true # unbuffer for clarity +disk_file.sync = false # buffered for speed +#----------------------------- +require 'socket' +sock = TCPSocket.new('www.ruby-lang.org', 80) +sock.sync = true +sock.puts "GET /en/ HTTP/1.0 \n\n" +resp = sock.read +print "DOC IS: #{resp}\n" + + +# @@PLEAC@@_7.13 +#----------------------------- +# assumes fh1, fh2, fh2 are oen IO objects +nfound = select([$stdin, fh1, fh2, fh3], nil, nil, 0) +nfound[0].each do |file| + case file + when fh1 + # do something with fh1 + when fh2 + # do something with fh2 + when fh3 + # do something with fh3 + end +end +#----------------------------- +input_files = [] +# repeat next line for all in-files to poll +input_files << fh1 +if nfound = select(input_files, nil, nil, 0) + # input ready on files in nfound[0] +end + + +# @@PLEAC@@_8.0 +#----------------------------- +# datafile is a file or IO object +datafile.readlines.each { |line| + line.chomp! + size = line.length + puts size +} +#----------------------------- +datafile.readlines.each { |line| + puts line.chomp!.length +} +#----------------------------- +lines = datafile.readlines +#----------------------------- +whole_file = file.read +#----------------------------- +# ruby -040 -e 'word = gets; puts "First word is #{word}"' +#----------------------------- +# ruby -ne 'BEGIN { $/="%%\n" }; $_.chomp; puts $_ if( $_=~/Unix/i)' fortune.dat +#----------------------------- +handle.print "one", "two", "three" # "onetwothree" +puts "Baa baa black sheep." # sent to $stdout +#----------------------------- +buffer = handle.read(4096) +rv = buffer.length +#----------------------------- +handle.truncate(length) +open("/tmp#{$$}.pid", 'w') { |handle| handle.truncate(length) } +#----------------------------- +pos = datafile.pos # tell is an alias of pos +puts "I'm #{pos} bytes from the start of datafile" +#----------------------------- +logfile.seek(0, IO::SEEK_END) +datafile.seek(pos) # IO::SEEK_SET is the default +out.seek(-20, IO::SEEK_CUR) +#----------------------------- +written = datafile.syswrite(mystring) +raise RunTimeError unless written == mystring.length +block = infile.sysread(256) # no equivalent to perl offset parameter in sysread +puts "only read #{block.length} bytes" if 256 != block.length +#----------------------------- +pos = handle.sysseek(0, IO::SEEK_CUR) # don't change position + + +# @@PLEAC@@_8.1 +while (line = fh.gets) + line.chomp! + nextline = nil + line.gsub!(/\\$/) { |match| nextline = fh.gets; '' } + if (nextline != nil) + line += nextline + redo + end + # process full record in line here +end +#----------------------------- +# DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ +# $(TEXINFOS) $(INFOS) $(MANS) $(DATA) +# DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ +# $(TEXINFOS) $(INFO_DEPS) $(MANS) $(DATA) \ +# $(EXTRA_DIST) +#----------------------------- +line.gsub!(/\\\s*$/, '') { + # as before +} + + +# @@PLEAC@@_8.2 +#----------------------------- +count = `wc -l < #{filename}` +fail "wc failed: #{$?}" if $? != 0 +count.chomp! +#----------------------------- +count = 0 +File.open(file, 'r') { |fh| + count += 1 while fh.gets +} +# count now holds the number of lines read +#----------------------------- +count = 0 +while (chunk = file.sysread(2**16)) + count += chunk.count("\n") +end rescue EOFError +#----------------------------- +File.open(filename,'r') { |fh| + count += 1 while fh.gets +} +# count now holds the number of lines read +#----------------------------- +# As ruby doesn't quite have an equivalent to using a for +# statement as in perl, I threw this in +count = File.readlines(filename).size +#----------------------------- +1 while file.gets +count = $. +#----------------------------- +$/ = '' +open(filename, 'r') { |fh| + 1 while fh.gets + para_count = $. +} rescue fail("can't open #{filename}: $!") +#----------------------------- + + +# ^^PLEAC^^_8.3 +#----------------------------- +while (gets) + split.each { |chunk| + # do something with chunk + } +end +#----------------------------- +while (gets) + gsub(/(\w[\w'-]*)/) { |word| + # do something with word + } +end +#----------------------------- +# Make a word frequency count +# normally hashes can be created using {} or just Hash.new +# but we want the default value of an entry to be 0 instead +# of nil. (nil can't be incremented) +seen = Hash.new(0) +while (gets) + gsub(/(\w[\w'-]*)/) { |word| + seen[word.downcase] += 1 + } +end +# output hash in a descending numeric sort of its values +seen.sort { |a,b| b[1] <=> a[1] }.each do |k,v| + printf("%5d %s\n", v, k ) +end + +#----------------------------- +# Line frequency count +seen = Hash.new(0) +while (gets) + seen[$_.downcase] += 1 +end +seen.sort { |a,b| b[1] <=> a[1] }.each do |k,v| + printf("%5d %s\n", v, k ) +end +#----------------------------- + + +# @@PLEAC@@_8.4 +#----------------------------- +# instead of file handle FILE, we can just +# use a string containing the filename +File.readlines(file).each { |line| + # do something with line +} +#----------------------------- +File.readlines(file).reverse_each { |line| + # do something with line +} +#----------------------------- +# the variable lines might have been created +# this way +# lines = File.readlines(file) +# +# normally one would use the reverse_each, but +# if you insist on using a numerical index to +# iterate over the lines array... +(lines.size - 1).downto(0) { |i| + line = lines[i] +} +#----------------------------- +# the second readlines argument is a the +# record separator $/, just like perl, a blank +# separator splits the records into paragraphs +File.readlines(file, '').each { |paragraph| + # do something with paragraph + puts "->Paragraph #{paragraph}" +} +#----------------------------- + + +# @@PLEAC@@_8.6 + +$/ = "%\n"; +srand; + +File.open('/usr/share/fortune/humorists').each do |line| + adage = line if rand($.) < 1 +end + +puts adage; + + +# @@PLEAC@@_8.10 +begin + fh = File.open(file, "r+") + addr = fh.tell unless fh.eof while fh.gets + fh.truncate(addr) +rescue SystemCallError + $stderr.puts "#$!" +end + + +# @@PLEAC@@_9.0 +entry = File.stat("/usr/bin/vi") +entry = File.stat("/usr/bin") +entry = File.stat(INFILE) + +entry = File.stat("/usr/bin/vi") +ctime = entry.ctime +size = entry.size + +f = File.open(filename, "r") + +## There is no -T equivalent in Ruby, but we can still test emptiness +if test(?s, filename) + puts "#{filename} doesn't have text in it." + exit +end + +Dir.new("/usr/bin").each do |filename| + puts "Inside /usr/bin is something called #{filename}" +end + + +# @@PLEAC@@_9.1 +file = File.stat("filename") +readtime, writetime = file.atime, file.mtime +file.utime(readtime, writetime) + +SECONDS_PER_DAY = 60 * 60 * 24 +file = File.stat("filename") +atime, mtime = file.atime, file.mtime + +atime -= 7 * SECONDS_PER_DAY +mtime -= 7 * SECONDS_PER_DAY + +File.utime(atime, mtime, file) +mtime = File.stat(file).mtime +File.utime(Time.new, mtime, file) +File.utime(Time.new, File.stat("testfile").mtime, file) + +#----------------------------- +#!/usr/bin/ruby -w +## uvi - vi a file without changing it's access times + +if ARGV.length != 1 + puts "usage: uvi filename" + exit +end +file = ARGV[0] +atime, mtime = File.stat(file).atime, File.stat(file).mtime +system(ENV["EDITOR"] || "vi", file) +File.utime(atime, mtime, file) +#----------------------------- + + +# @@PLEAC@@_9.2 +File.unlink(FILENAME) + +err_flg = false +filenames.each do |file| + begin + File.unlink(file) + rescue + err_flg = $! + end +end +err_flg and raise "Couldn't unlink all of #{filenames.join(" ")}: #{err_flg}" + +File.unlink(file) + +count = filenames.length +filenames.each do |file| + begin + File.unlink(file) + rescue + count -= 1 + end +end +if count != filenames.length + STDERR.puts "could only delete #{count} of #{filenames.length} files" +end + + +# @@PLEAC@@_9.3 +require "ftools" +File.copy(oldfile, newfile) + +infile = File.open(oldfile, "r") +outfile = File.open(newfile, "w") + +blksize = infile.stat.blksize +# This doesn't handle partial writes or ^Z +# like the Perl version does. +while (line = infile.read(blksize)) + outfile.write(line) +end + +infile.close +outfile.close + +system("cp #{oldfile} #{newfile}") # unix +system("copy #{oldfile} #{newfile}") # dos, vms + +require "ftools" +File.copy("datafile.dat", "datafile.bak") +File.move("datafile.new", "datafile.dat") + + +# @@PLEAC@@_9.4 +$seen = {} # must use global var to be seen inside of method below + +def do_my_thing(filename) + dev, ino = File.stat(filename).dev, File.stat(filename).ino + unless $seen[[dev, ino]] + # do something with $filename because we haven't + # seen it before + end + $seen[[dev, ino]] = $seen[[dev, ino]].to_i + 1 +end + +files.each do |filename| + dev, ino = File.stat(filename).dev, File.stat(filename).ino + if !$seen.has_key?([dev, ino]) + $seen[[dev, ino]] = [] + end + $seen[[dev, ino]].push(filename) +end + +$seen.keys.sort.each do |devino| + ino, dev = devino + if $seen[devino].length > 1 + # $seen[devino] is a list of filenames for the same file + end +end + + +# @@PLEAC@@_9.5 +Dir.open(dirname) do |dir| + dir.each do |file| + # do something with dirname/file + puts file + end +end +# Dir.close is automatic + +# No -T equivalent in Ruby + +dir.each do |file| + next if file =~ /^\.\.?$/ + # ... +end + +def plainfiles(dir) + dh = Dir.open(dir) + dh.entries.grep(/^[^.]/). + map {|file| "#{dir}/#{file}"}. + find_all {|file| test(?f, file)}. + sort +end + + +# @@PLEAC@@_9.6 +list = Dir.glob("*.c") + +dir = Dir.open(path) +files = dir.entries.grep(/\.c$/) +dir.close + +files = Dir.glob("*.c") +files = Dir.open(path).entries.grep(/\.[ch]$/i) + +dir = Dir.new(path) +files = dir.entries.grep(/\.[ch]$/i) + +begin + d = Dir.open(dir) +rescue Errno::ENOENT + raise "Couldn't open #{dir} for reading: #{$!}" +end + +files = [] +d.each do |file| + puts file + next unless file =~ /\.[ch]$/i + + filename = "#{dir}/#{file}" + # There is no -T equivalent in Ruby, but we can still test emptiness + files.push(filename) if test(?s, filename) +end + +dirs.entries.grep(/^\d+$/). + map { |file| [file, "#{path}/#{file}"]} . + select { |file| test(?d, file[1]) }. + sort { |a,b| a[0] <=> b[0] }. + map { |file| file[1] } + + +# @@PLEAC@@_9.7 +require 'find' +Find.find(dirlist) do |file| + # do whatever +end + +require 'find' +argv = ARGV.empty? ? %w{.} : ARGV +Find.find(*argv) do |file| + print file, (test(?d, file) ? "/\n" : "\n") +end + +require 'find' +argv = ARGV.empty? ? %w{.} : ARGV +sum = 0 +Find.find(*argv) do |file| + size = test(?s, file) || 0 + sum += size +end +puts "#{argv.join(' ')} contains #{sum} bytes" + +require 'find' +argv = ARGV.empty? ? %w{.} : ARGV +saved_size, saved_name = -1, "" +Find.find(*argv) do |file| + size = test(?s, file) || 0 + next unless test(?f, file) && size > saved_size + saved_size = size + saved_name = file +end +puts "Biggest file #{saved_name} in #{argv.join(' ')} is #{saved_size}" + +require 'find' +argv = ARGV.empty? ? %w{.} : ARGV +age, name = nil +Find.find(*argv) do |file| + mtime = File.stat(file).mtime + next if age && age > mtime + age = mtime + name = file +end +puts "#{name} #{age}" + +#----------------------------- +#!/usr/bin/ruby -w +# fdirs - find all directories +require 'find' +argv = ARGV.empty? ? %w{.} : ARGV +File.find(*argv) { |file| puts file if test(?d, file) } +#----------------------------- + + +# @@PLEAC@@_9.8 +require 'fileutils' + +puts "Usage #{$0} dir ..." if ARGV.empty? +ARGV.each do |dir| + FileUtils.rmtree(dir) +end + + +# @@PLEAC@@_9.9 +require 'ftools' +names.each do |file| + newname = file + begin + File.move(file, newname) + rescue Errno::EPERM + $stderr.puts "Couldn't rename #{file} to #{newname}: #{$!}" + end +end + +require 'ftools' +op = ARGV.empty? ? (raise "Usage: rename expr [files]\n") : ARGV.shift +argv = ARGV.empty? ? $stdin.readlines.map { |f| f.chomp } : ARGV +argv.each do |file| + was = file + file = eval("file.#{op}") + File.move(was, file) unless was == file +end + + +# @@PLEAC@@_9.10 +base = File.basename(path) +dir = File.dirname(path) +# ruby has no fileparse equivalent +dir, base = File.split(path) +ext = base.scan(/\..*$/).to_s + +path = '/usr/lib/libc.a' +file = File.basename(path) +dir = File.dirname(path) + +puts "dir is #{dir}, file is #{file}" +# dir is /usr/lib, file is libc.a + +path = '/usr/lib/libc.a' +dir, filename = File.split(path) +name, ext = filename.split(/(?=\.)/) +puts "dir is #{dir}, name is #{name}, ext is #{ext}" +# NOTE: The Ruby code prints +# dir is /usr/lib, name is libc, extension is .a +# while the Perl code prints a '/' after the directory name +# dir is /usr/lib/, name is libc, extension is .a + +# No fileparse_set_fstype() equivalent in ruby + +def extension(path) + ext = path.scan(/\..*$/).to_s + ext.sub(/^\./, "") +end + + +# @@PLEAC@@_9.11 +#----------------------------- +#!/usr/bin/ruby -w +# symirror - build spectral forest of symlinks + +require 'find' +require 'fileutils' + +raise "usage: #{$0} realdir mirrordir" unless ARGV.size == 2 + +srcdir,dstdir = ARGV +srcmode = File::stat(srcdir).mode +Dir.mkdir(dstdir, srcmode & 07777) unless test(?d, dstdir) + +# fix relative paths +Dir.chdir(srcdir) {srcdir = Dir.pwd} +Dir.chdir(dstdir) {dstdir = Dir.pwd} + +Find.find(srcdir) do |srcfile| + if test(?d, srcfile) + dest = srcfile.sub(/^#{srcdir}/, dstdir) + dmode = File::stat(srcfile).mode & 07777 + Dir.mkdir(dest, dmode) unless test(?d, dest) + a = Dir["#{srcfile}/*"].reject{|f| test(?d, f)} + FileUtils.ln_s(a, dest) + end +end + + +# @@PLEAC@@_9.12 +# we use the Getopt/Declare library here for convenience: +# http://raa.ruby-lang.org/project/getoptdeclare/ +#----------------------------- +#!/usr/bin/ruby -w +# lst - list sorted directory contents (depth first) + +require 'find' +require 'etc' +require "Getopt/Declare" + +# Note: in the option-spec below there must by at least one hard +# tab in between each -option and its description. For example +# -i <tab> read from stdin + +opts = Getopt::Declare.new(<<'EOPARAM') + ============ + Input Format: + -i read from stdin + ============ + Output Format: + -l long listing + -r reverse listing + ============ + Sort on: (one of) + -m mtime (modify time - default) + {$sort_criteria = :mtime} + -u atime (access time) + {$sort_criteria = :atime} + -c ctime (inode change time) + {$sort_criteria = :ctime} + -s size + {$sort_criteria = :size} + [mutex: -m -u -c -s] + +EOPARAM + +$sort_criteria ||= :mtime +files = {} +DIRS = opts['-i'] ? $stdin.readlines.map{|f|f.chomp!} : ARGV +DIRS.each do |dir| + Find.find(dir) do |ent| + files[ent] = File::stat(ent) + end +end +entries = files.keys.sort_by{|f| files[f].send($sort_criteria)} +entries = entries.reverse unless opts['-r'] + +entries.each do |ent| + unless opts['-l'] + puts ent + next + end + stats = files[ent] + ftime = stats.send($sort_criteria == :size ? :mtime : $sort_criteria) + printf "%6d %04o %6d %8s %8s %8d %s %s\n", + stats.ino, + stats.mode & 07777, + stats.nlink, + ETC::PASSWD[stats.uid].name, + ETC::GROUP[stats.gid].name, + stats.size, + ftime.strftime("%a %b %d %H:%M:%S %Y"), + ent +end + + +# @@PLEAC@@_10.0 +def hello + $greeted += 1 # in Ruby, a variable beginning with $ is global (can be any type of course) + puts "hi there!" +end + +# We need to initialize $greeted before it can be used, because "+=" is waiting a Numeric object +$greeted = 0 +hello # note that appending () is optional to function calls with no parameters + + +# @@PLEAC@@_10.1 +# In Ruby, parameters are named anyway +def hypotenuse(side1, side2) + Math.sqrt(side1**2 + side2**2) # the sqrt function comes from the Math module +end +diag = hypotenuse(3, 4) + +puts hypotenuse(3, 4) + +a = [3, 4] +print hypotenuse(*a) # the star operator will magically convert an Array into a "tuple" + +both = men + women + +# In Ruby, all objects are references, so the same problem arises; we then return a new object +nums = [1.4, 3.5, 6.7] +def int_all(n) + n.collect { |v| v.to_i } +end +ints = int_all(nums) + +nums = [1.4, 3.5, 6.7] +def trunc_em(n) + n.collect! { |v| v.to_i } # the bang-version of collect modifies the object +end +trunc_em(nums) + +# Ruby has two chomp version: +# ``chomp'' chomps the record separator and returns what's expected +# ``chomp!'' does the same but also modifies the parameter object + + +# @@PLEAC@@_10.2 +def somefunc + variable = something # variable is local by default +end + +name, age = ARGV +start = fetch_time + +a, b = pair # will succeed if pair is an Array object (like ARGV is) +c = fetch_time + +# In ruby, run_check can't access a, b, or c until they are +# explicitely defined global (using leading $), even if they are +# both defined in the same scope + +def check_x(x) + y = "whatever" + run_check + if $condition + puts "got $x" + end +end + +# The following will keep a reference to the array, though the +# results will be slightly different from perl: the last element +# of $global_array will be itself an array +def save_array(ary) + $global_array << ary +end + +# The following gives the same results as in Perl for $global_array, +# though it doesn't illustrate anymore the way to keep a reference +# to an object: $global_array is extended with the elements of ary +def save_array(ary) + $global_array += ary +end + + +# @@PLEAC@@_10.3 +# In Ruby, AFAIK a method cannot access "local variables" defined +# upper scope; mostly because everything is an object, so you'll +# do the same by defining an attribute or a static attribute + +# In Ruby the BEGIN also exists: +BEGIN { puts "hello from BEGIN" } +puts "hello from main" +BEGIN { puts "hello from 2nd BEGIN" } +# gives: +# hello from BEGIN +# hello from 2nd BEGIN +# hello from main + +# In Ruby, it can be written as a static method and a static +# variable +class Counter + @@counter = 0 + def Counter.next_counter; @@counter += 1; end +end + +# There is no need of BEGIN since the variable will get +# initialized when parsing +class Counter + @@counter = 42 + def Counter.next_counter; @@counter += 1; end + def Counter.prev_counter; @@counter -= 1; end +end + + +# @@PLEAC@@_10.4 +# You can either get the whole trace as an array of strings, each +# string telling which file, line and method is calling: +caller + +# ...or only the last caller +caller[0] + +# We need to extract just the method name of the backtrace: +def whoami; caller()[0] =~ /in `([^']+)'/ ? $1 : '(anonymous)'; end +def whowasi; caller()[1] =~ /in `([^']+)'/ ? $1 : '(anonymous)'; end + + +# @@PLEAC@@_10.5 +# In Ruby, every value is a reference on an object, thus there is +# no such problem +array_diff(array1, array2) + +def add_vecpair(a1, a2) + results = [] + a1.each_index { |i| results << (a1[i] + a2[i]) } + results +end +a = [1, 2] +b = [5, 8] +c = add_vecpair(a, b) +p c + +# Add this to the beginning of the function to check if we were +# given two arrays +a1.type == Array && a2.type == Array or + raise "usage: add_vecpair array1 array2 (was used with: #{a1.type} #{a2.type})" + + +# @@PLEAC@@_10.6 +# There is no return context in Ruby + + +# @@PLEAC@@_10.7 +# Like in Perl, we need to fake with a hash, but it's dirty :-( +def thefunc(param_args) + args = { 'INCREMENT' => '10s', 'FINISH' => '0', 'START' => 0 } + args.update(param_args) + if (args['INCREMENT'] =~ /m$/ ) + # ..... + end +end + +thefunc({ 'INCREMENT' => '20s', 'START' => '+5m', 'FINISH' => '+30m' }) +thefunc({}) + + +# @@PLEAC@@_10.8 +# there is no "undef" direct equivalent but there is the slice equiv: +a, c = func.indexes(0, 2) + + +# @@PLEAC@@_10.9 +# Ruby has no such limitation: +def somefunc + ary = [] + hash = {} + # ... + return ary, hash +end +arr, dict = somefunc + +array_of_hashes = fn +h1, h2, h3 = fn + + +# @@PLEAC@@_10.10 +return +# or (equivalent) +return nil + + +# @@PLEAC@@_10.11 +# You can't prototype in Ruby regarding types :-( +# Though, you can force the number of arguments: +def func_with_no_arg; end +def func_with_no_arg(); end +def func_with_one_arg(a1); end +def func_with_two_args(a1, a2); end +def func_with_any_number_of_args(*args); end + + +# @@PLEAC@@_10.12 +raise "some message" # raise exception + +begin + val = func +rescue Exception => msg + $stderr.puts "func raised an exception: #{msg}" +end + +# In Ruby the rescue statement uses an exception class, every +# exception which is not matched is still continuing +begin + val = func +rescue FullMoonError + ... +end + + +# @@PLEAC@@_10.13 +# Saving Global Values +# Of course we can just save the value and restore it later: +def print_age + puts "Age is #{$age}" +end + +$age = 18 # global variable +print_age() +if condition + safeage = $age + $age = 23 + print_age() + $age = safeage +end + +# We can also use a method that saves the global variable and +# restores it automatically when the block is left: + +def local(var) + eval("save = #{var.id2name}") + begin + result = yield + ensure + # we want to call this even if we got an exception + eval("#{var.id2name} = save") + end + result +end + +condition = true +$age = 18 +print_age() +if condition + local(:$age) { + $age = 23 + print_age() + } +end +print_age() + +# There is no need to use local() for filehandles or directory +# handles in ruby because filehandles are normal objects. + + +# @@PLEAC@@_10.14 +# In Ruby you may redefine a method [but not overload it :-(] +# just by defining again with the same name. +def foo; puts 'foo'; end +def foo; puts 'bar'; end +foo +#=> bar + +# You can also take a reference to an existing method before +# redefining a new one, using the `alias' keyword +def foo; puts 'foo'; end +alias foo_orig foo +def foo; puts 'bar'; end +foo_orig +foo +#=> foo +#=> bar + +# AFAIK, there is no direct way to create a new method whose name +# comes from a variable, so use "eval" +colors = %w(red blue green yellow orange purple violet) +colors.each { |c| + eval <<-EOS + def #{c}(*a) + "<FONT COLOR='#{c}'>" + a.to_s + "</FONT>" + end + EOS +} + + +# @@PLEAC@@_10.15 +def method_missing(name, *args) + "<FONT COLOR='#{name}'>" + args.join(' ') + "</FONT>" +end +puts chartreuse("stuff") + + +# @@PLEAC@@_10.16 +def outer(arg) + x = arg + 35 + inner = proc { x * 19 } + x + inner.call() +end + + +# @@PLEAC@@_10.17 +#!/usr/bin/ruby -w +# mailsort - sort mbox by different criteria +require 'English' +require 'Date' + +# Objects of class Mail represent a single mail. +class Mail + attr_accessor :no + attr_accessor :subject + attr_accessor :fulltext + attr_accessor :date + + def initialize + @fulltext = "" + @subject = "" + end + + def append(para) + @fulltext << para + end + + # this is called if you call puts(mail) + def to_s + @fulltext + end +end + +# represents a list of mails. +class Mailbox < Array + + Subjectpattern = Regexp.new('Subject:\s*(?:Re:\s*)*(.*)\n') + Datepattern = Regexp.new('Date:\s*(.*)\n') + + # reads mails from open file and stores them + def read(file) + $INPUT_RECORD_SEPARATOR = '' # paragraph reads + msgno = -1 + file.each { |para| + if para =~ /^From/ + mail = Mail.new + mail.no = (msgno += 1) + md = Subjectpattern.match(para) + if md + mail.subject = md[1] + end + md = Datepattern.match(para) + if md + mail.date = DateTime.parse(md[1]) + else + mail.date = DateTime.now + end + self.push(mail) + end + mail.append(para) if mail + } + end + + def sort_by_subject_and_no + self.sort_by { |m| + [m.subject, m.no] + } + end + + # sorts by a list of attributs of mail, given as symbols + def sort_by_attributs(*attrs) + # you can sort an Enumerable by an array of + # values, they would be compared + # from ary[0] to ary[n]t, say: + # ['b',1] > ['a',10] > ['a',9] + self.sort_by { |elem| + attrs.map { |attr| + elem.send(attr) + } + } + end + +end + +mailbox = Mailbox.new +mailbox.read(ARGF) + +# print only subjects sorted by subject and number +for m in mailbox.sort_by_subject_and_no + puts(m.subject) +end + +# print complete mails sorted by date, then subject, then number +for m in mailbox.sort_by_attributs(:date, :subject) + puts(m) +end + + +# @@PLEAC@@_11.7 +def mkcounter(count) + start = count + bundle = { + "NEXT" => proc { count += 1 }, + "PREV" => proc { count -= 1 }, + "RESET" => proc { count = start } + } + bundle["LAST"] = bundle["PREV"] + return bundle +end + +c1 = mkcounter(20) +c2 = mkcounter(77) + +puts "next c1: #{c1["NEXT"].call}" # 21 +puts "next c2: #{c2["NEXT"].call}" # 78 +puts "next c1: #{c1["NEXT"].call}" # 22 +puts "last c1: #{c1["PREV"].call}" # 21 +puts "last c1: #{c1["LAST"].call}" # 20 +puts "old c2: #{c2["RESET"].call}" # 77 + + +# @@PLEAC@@_11.15 +class Binary_tree + def initialize(val) + @value = val + @left = nil + @right = nil + end + + # insert given value into proper point of + # provided tree. If no tree provided, + # use implicit pass by reference aspect of @_ + # to fill one in for our caller. + def insert(val) + if val < @value then + if @left then + @left.insert(val) + else + @left = Binary_tree.new(val) + end + elsif val > @value then + if @right then + @right.insert(val) + else + @right = Binary_tree.new(val) + end + else + puts "double" + # do nothing, no double values + end + end + + # recurse on left child, + # then show current value, + # then recurse on right child. + def in_order + @left.in_order if @left + print @value, " " + @right.in_order if @right + end + + # show current value, + # then recurse on left child, + # then recurse on right child. + def pre_order + print @value, " " + @left.pre_order if @left + @right.pre_order if @right + end + + # recurse on left child, + # then recurse on right child, + # then show current value. + def post_order + @left.post_order if @left + @right.post_order if @right + print @value, " " + end + + # find out whether provided value is in the tree. + # if so, return the node at which the value was found. + # cut down search time by only looking in the correct + # branch, based on current value. + def search(val) + if val == @value then + return self + elsif val < @value then + return @left.search(val) if @left + return nil + else + return @right.search(val) if @right + return nil + end + end +end + +# first generate 20 random inserts +test = Binary_tree.new(0) +for a in 0..20 + test.insert(rand(1000)) +end + +# now dump out the tree all three ways +print "Pre order: "; test.pre_order; puts "" +print "In order: "; test.in_order; puts "" +print "Post order: "; test.post_order; puts "" + +print "search?" +while gets + print test.search($_.to_i) + print "\nsearch?" +end + + +# @@PLEAC@@_12.0 +# class and module names need to have the first letter capitalized +module Alpha + NAME = 'first' +end +module Omega + NAME = 'last' +end +puts "Alpha is #{Alpha::NAME}, Omega is #{Omega::NAME}" + +# ruby doesn't differentiate beteen compile-time and run-time +require 'getoptlong.rb' +require 'getoptlong' # assumes the .rb +require 'cards/poker.rb' +require 'cards/poker' # assumes the .rb +load 'cards/poker' # require only loads the file once + +module Cards + module Poker + @card_deck = Array.new # or @card_deck = [] + def shuffle + end + end +end + + +# @@PLEAC@@_12.1 +# a module exports all of its functions +module Your_Module + def self.function + # this would be called as Your_Module.function + end + + def Your_Module.another + # this is the same as above, but more specific + end +end + +# @@PLEAC@@_12.2 +begin + require 'nonexistent' +rescue LoadError + puts "Couldn't load #{$!}" # $! contains the last error string +end + +# @@PLEAC@@_12.4 +# module variables are private unless access functions are defined +module Alpha + @aa = 10 + @bb = 11 + + def self.put_aa + puts @aa + end + + def self.bb=(val) + @bb = val + end +end + +Alpha.bb = 12 +# Alpha.aa = 10 # error, no aa=method + + +# @@PLEAC@@_12.5 +# caller provides a backtrace of the call stack +module MyModule + def find_caller + caller + end + + def find_caller2(i) + caller(i) # an argument limits the size of the stack returned + end +end + + +# @@PLEAC@@_12.6 +BEGIN { + $logfile = '/tmp/mylog' unless defined? $logfile + $LF = File.open($logfile, 'a') +} + +module Logger + def self.logmsg(msg) + $LF.puts msg + end + + logmsg('startup') +end + +END { + Logger::logmsg('shutdown') + $LF.close +} + + +# @@PLEAC@@_12.7 +#----------------------------- +# results may be different on your system +# % ruby -e "$LOAD_PATH.each_index { |i| printf("%d %s\n", i, $LOAD_PATH[i] } +#0 /usr/local/lib/site_ruby/1.6 +#1 /usr/local/lib/site_ruby/1.6/i386-linux +#2 /usr/local/lib/site_ruby/ +#3 /usr/lib/ruby/1.6 +#4 /usr/lib/ruby/1.6/i136-linux +#5 . +#----------------------------- +# syntax for sh, bash, ksh, or zsh +#$ export RUBYLIB=$HOME/rubylib + +# syntax for csh or tcsh +# % setenv RUBYLIB ~/rubylib +#----------------------------- +$LOAD_PATH.unshift "/projects/spectre/lib"; + + +# @@PLEAC@@_12.8 +# equivalents in ruby are mkmf, SWIG, or Ruby/DL depending on usage + + +# @@PLEAC@@_12.9 +# no equivalent in ruby + + +# @@PLEAC@@_12.10 +# no equivalent in ruby + + +# @@PLEAC@@_12.11 +module FineTime + def self.time + # to be defined later + end +end + + +module FineTime + def self.time + "its a fine time" + end +end + +puts FineTime.time #=> "its a fine time" + + +# @@PLEAC@@_12.12 +def even_only(n) + raise "#{n} is not even" if (n & 1) != 0 # one way to test + # ... +end +def even_only(n) + $stderr.puts "#{n} is not even" if (n & 1) != 0 + # ... +end + + +# @@PLEAC@@_12.17 +# The library archive for ruby is called Ruby Application archive, +# or shorter RAA, and can be found at http://raa.ruby-lang.org. +# A typical library is installed like this: +# % gunzip some-module-4.54.tar.gz +# % tar xf some-module-4.54.tar +# % cd some-module-4.54.tar +# % ruby install.rb config +# % ruby install.rb setup +# get superuser previleges here if needed for next step +# % ruby install.rb install + +# Some modules use a different process, +# you should find details in the documentation +# Here is an example of such a different process +# % ruby extconf.rb +# % make +# % make install + +# If you want the module installed in your own directory: +# For ruby version specific libraries +# % ruby install.rb config --site-ruby=~/lib +# For version independent libraries +# % ruby install.rb config --site-ruby-common=~/lib + +# Information about possible options for config +# % ruby install.rb --help + +# If you have your own complete distribution +# % ruby install.rb --prefix=path=~/ruby-private + + +# @@PLEAC@@_13.0 +# Classes and objects in Ruby are rather straigthforward +class Person + # Class variables (also called static attributes) are prefixed by @@ + @@person_counter=0 + + # object constructor + def initialize(age, name, alive = true) # Default arg like in C++ + @age, @name, @alive = age, name, alive # Object attributes are prefixed by '@' + @@person_counter += 1 + # There is no '++' operator in Ruby. The '++'/'--' operators are in fact + # hidden assignments which affect variables, not objects. You cannot accomplish + # assignment via method. Since everything in Ruby is object, '++' and '--' + # contradict Ruby OO ideology. Instead '-=' and '+=' are used. + end + + attr_accessor :name, :age # This creates setter and getter methods for @name + # and @age. See 13.3 for detailes. + + # methods modifying the receiver object usually have the '!' suffix + def die! + @alive = false + puts "#{@name} has died at the age of #{@age}." + @alive + end + + def kill(anotherPerson) + print @name, ' is killing ', anotherPerson.name, ".\n" + anotherPerson.die! + end + + # methods used as queries + # usually have the '?' suffix + def alive? + @alive && true + end + + def year_of_birth + Time.now.year - @age + end + + # Class method (also called static method) + def Person.number_of_people + @@person_counter + end +end + +# Using the class: +# Create objects of class Person +lecter = Person.new(47, 'Hannibal') +starling = Person.new(29, 'Clarice', true) +pazzi = Person.new(40, 'Rinaldo', true) + +# Calling a class method +print "There are ", Person.number_of_people, " Person objects\n" + +print pazzi.name, ' is ', (pazzi.alive?) ? 'alive' : 'dead', ".\n" +lecter.kill(pazzi) +print pazzi.name, ' is ', (pazzi.alive?) ? 'alive' : 'dead', ".\n" + +print starling.name , ' was born in ', starling.year_of_birth, "\n" + + +# @@PLEAC@@_13.1 +# If you don't need any initialisation in the constructor, +# you don't need to write a constructor. +class MyClass +end + +class MyClass + def initialize + @start = Time.new + @age = 0 + end +end + +class MyClass + def initialize(inithash) + @start = Time.new + @age = 0 + for key, value in inithash + instance_variable_set("@#{key}", value) + end + end +end + +# @@PLEAC@@_13.2 +# Objects are destroyed by the garbage collector. +# The time of destroying is not predictable. +# The ruby garbage collector can handle circular references, +# so there is no need to write destructor for that. + +# There is no direct support for destructor. +# You can call a custom function, or more specific a proc object, when the +# garbage collector is about to destruct the object, but it is unpredictable +# when this occurs. +# Also if such a finalizer object has a reference to the orignal object, +# this may prevent the original object to get garbage collected. +# Because of this problem the finalize method below is +# a class method and not a instance method. +# So if you need to free resources for an object, like +# closing a socket or kill a spawned subprocess, +# you should do it explicitly. + +class MyClass + def initialize + ObjectSpace.define_finalizer(self, + self.class.method(:finalize).to_proc) + end + def MyClass.finalize(id) + puts "Object #{id} dying at #{Time.new}" + end +end + +# test code +3.times { + MyClass.new +} +ObjectSpace.garbage_collect + + +# @@PLEAC@@_13.3 +# You can write getter and setter methods in a natural way: +class Person + def name + @name + end + def name=(name) + @name = name + end +end + +# But there is a better and shorter way +class Person + attr_reader :age + attr_writer :name + # attr_reader and attr_writer are actually methods in class Class + # which set getter and setter methods for you. +end + +# There is also attr_accessor to create both setters and getters +class Person + attr_accessor :age, :name +end + + +# @@PLEAC@@_13.4 +class Person + # Class variables (also called static attributes) are prefixed by @@ + @@person_counter = 0 + + def Person.population + @@person_counter + end + def initialize + @@person_counter += 1 + ObjectSpace.define_finalizer(self, + self.class.method(:finalize).to_proc) + end + def Person.finalize(id) + @@person_counter -= 1 + end +end +people = [] +10.times { + people.push(Person.new) +} +printf("There are %d people alive", Person.population) + + +FixedArray.class_max_bounds = 100 +alpha = FixedArray.new +puts "Bound on alpha is #{alpha.max_bounds}" + +beta = FixedArray.new +beta.max_bounds = 50 # calls the instance method +beta.class.class_max_bounds = 50 # alternative, calls the class method +puts "Bound on alpha is #{alpha.max_bounds}" + +class FixedArray + @@bounds = 7 + + def max_bounds + @@max_bounds + end + # instance method, which sets the class variable + def max_bounds=(value) + @@max_bounds = value + end + # class method. This can only be called on a class, + # but not on the instances + def FixedArray.class_max_bounds=(value) + @@max_bounds = value + end +end + + +# @@PLEAC@@_13.5 +PersonStruct = Struct.new("Person", :name, :age, :peers) +# creates a class "Person::Struct", which is accessiable with the +# constant "PersonStruct" +p = PersonStruct.new +p = Struct::Person.new # alternative using the classname +p.name = "Jason Smythe" +p.age = 13 +p.peers = ["Wilbur", "Ralph", "Fred"] +p[:peers] = ["Wilbur", "Ralph", "Fred"] # alternative access using symbol +p["peers"] = ["Wilbur", "Ralph", "Fred"] # alternative access using name of field +p[2] = ["Wilbur", "Ralph", "Fred"] # alternative access using index of field +puts "At age #{p.age}, #{p.name}'s first friend is #{p.peers[0]}" + +# The fields of a struct have no special type, like other ruby variables +# you can put any objects in. Therefore the discussions how to specify +# the types of the fields do not apply to ruby. + +FamilyStruct = Struct.new("Family", :head, :address, :members) +folks = FamilyStruct.new +folks.head = PersonStruct.new +dad = folks.head +dad.name = "John" +dad.age = 34 + +# supply of own accessor method for the struct for error checking +class PersonStruct + def age=(value) + if !value.kind_of?(Integer) + raise(ArgumentError, "Age #{value} isn't an Integer") + elsif value > 150 + raise(ArgumentError, "Age #{value} is unreasonable") + end + @age = value + end +end + + +# @@PLEAC@@_13.6 +# The ruby Object class defines a dup and a clone method. +# The dup method is recommended for prototype object creation. +# The default implementation makes a shallow copy, +# but each class can override it, for example to make a deep copy. + +# If you want to call 'new' directly on the instances, +# you can create a instance method "new", which returns a new duplicate. +# This method is distinct from the class method new. +# +class A + def new + dup + end +end + +ob1 = A.new +# later on +ob2 = ob1.new + + +# @@PLEAC@@_13.7 +methname = 'flicker' +obj.send(methname, 10) # calls obj.flicker(10) + +# call three methods on the object, by name +['start', 'run', 'stop'].each do |method_string| + obj.send(method_string) +end + +# Another way is to create a Method object +method_obj = obj.method('flicker') +# And then call it +method_obj.call(10) + + +# @@PLEAC@@_13.8 +# All classes in Ruby inherit from class Object +# and thus all objects share methods defined in this class + +# the class of the object +puts any_object.type + +# Ruby classes are actually objects of class Class and they +# respond to methods defined in Object class as well + +# the superclass of this class +puts any_object.class.superclass + +# ask an object whether it is an instance of particular class +n = 4.7 +puts n.instance_of?(Float) # true +puts n.instance_of?(Numeric) # false + +# ask an object whether it is an instance of class, one of the +# superclasses of the object, or modules included in it +puts n.kind_of?(Float) # true (the class) +puts n.kind_of?(Numeric) # true (an ancestor class) +puts n.kind_of?(Comparable) # true (a mixin module) +puts n.kind_of?(String) # false + +# ask an object whether it can respond to a particular method +puts n.respond_to?('+') # true +puts n.respond_to?('length') # false + +# all methods an object can respond to +'just a string'.methods.each { |m| puts m } + + +# @@PLEAC@@_13.9 +# Actually any class in Ruby is inheritable +class Person + attr_accessor :age, :name + def initialize + @name + @age + end +end +#----------------------------- +dude = Person.new +dude.name = 'Jason' +dude.age = 23 +printf "%s is age %d.\n", dude.name, dude.age +#----------------------------- +# Inheriting from Person +class Employee < Person + attr_accessor :salary +end +#----------------------------- +empl = Employee.new +empl.name = 'Jason' +empl.age = 23 +empl.salary = 200 +printf "%s is age %d, the salary is %d.\n", empl.name, empl.age, empl.salary +#----------------------------- +# Any built-in class can be inherited the same way +class WeirdString < String + def initialize(obj) + super obj + end + def +(anotherObj) # + method in this class is overridden + # to return the sum of string lengths + self.length + anotherObj.length # 'self' can be omitted + end +end +#----------------------------- +a = WeirdString.new('hello') +b = WeirdString.new('bye') + +puts a + b # the overridden + +#=> 8 +puts a.length # method from the superclass, String +#=> 5 + + +# @@PLEAC@@_13.11 +# In ruby you can override the method_missing method +# to have a solution similar to perls AUTOLOAD. +class Person + + def initialize + @ok_fields = %w(name age peers parent) + end + + def valid_attribute?(name) + @ok_fields.include?(name) + end + + def method_missing(namesymbol, *params) + name = namesymbol.to_s + return if name =~ /^A-Z/ + if name.to_s[-1] == ('='[0]) # we have a setter + isSetter = true + name.sub!(/=$/, '') + end + if valid_attribute?(name) + if isSetter + instance_variable_set("@#{name}", *params) + else + instance_variable_get("@#{name}", *params) + end + else + # if no annestor is responsible, + # the Object class will throw a NoMethodError exception + super(namesymbol, *params) + end + end + + def new + kid = Person.new + kid.parent = self + kid + end + +end + +dad = Person.new +dad.name = "Jason" +dad.age = 23 +kid = dad.new +kid.name = "Rachel" +kid.age = 2 +puts "Kid's parent is #{kid.parent.name}" +puts dad +puts kid + +class Employee < Person + def initialize + super + @ok_fields.push("salary", "boss") + end + def ok_fields + @ok_fields + end +end + + +# @@PLEAC@@_13.13 +# The ruby garbage collector pretends to cope with circular structures. +# You can test it with this code: +class RingNode + attr_accessor :next + attr_accessor :prev + attr_reader :name + + def initialize(aName) + @name = aName + ObjectSpace.define_finalizer(self, + self.class.method(:finalize).to_proc) + end + + def RingNode.finalize(id) + puts "Node #{id} dying" + end + + def RingNode.show_all_objects + ObjectSpace.each_object {|id| + puts id.name if id.class == RingNode + } + end +end + +def create_test + a = RingNode.new("Node A") + b = RingNode.new("Node B") + c = RingNode.new("Node C") + a.next = b + b.next = c + c.next = a + a.prev = c + c.prev = b + b.prev = a + + a = nil + b = nil + c = nil +end + +create_test +RingNode.show_all_objects +ObjectSpace.garbage_collect +puts "After garbage collection" +RingNode.show_all_objects + + +# @@PLEAC@@_13.14 +class String + def <=>(other) + self.casecmp other + end +end + +# There is no way to directly overload the '""' (stringify) +# operator in Ruby. However, by convention, classes which +# can reasonably be converted to a String will define a +# 'to_s' method as in the TimeNumber class defined below. +# The 'puts' method will automatcally call an object's +# 'to_s' method as is demonstrated below. +# Furthermore, if a class defines a to_str method, an object of that +# class can be used most any place where the interpreter is looking +# for a String value. + +#--------------------------------------- +# NOTE: Ruby has a builtin Time class which would usually be used +# to manipulate time objects, the following is supplied for +# educational purposes to demonstrate operator overloading. +# +class TimeNumber + attr_accessor :hours,:minutes,:seconds + def initialize( hours, minutes, seconds) + @hours = hours + @minutes = minutes + @seconds = seconds + end + + def to_s + return sprintf( "%d:%02d:%02d", @hours, @minutes, @seconds) + end + + def to_str + to_s + end + + def +( other) + seconds = @seconds + other.seconds + minutes = @minutes + other.minutes + hours = @hours + other.hours + if seconds >= 60 + seconds %= 60 + minutes += 1 + end + if minutes >= 60 + minutes %= 60 + hours += 1 + end + return TimeNumber.new(hours, minutes, seconds) + end + + def -(other) + raise NotImplementedError + end + + def *(other) + raise NotImplementedError + end + + def /( other) + raise NotImplementedError + end +end + +t1 = TimeNumber.new(0, 58, 59) +sec = TimeNumber.new(0, 0, 1) +min = TimeNumber.new(0, 1, 0) +puts t1 + sec + min + min + +#----------------------------- +# StrNum class example: Ruby's builtin String class already has the +# capabilities outlined in StrNum Perl example, however the '*' operator +# on Ruby's String class acts differently: It creates a string which +# is the original string repeated N times. +# +# Using Ruby's String class as is in this example: +x = "Red"; y = "Black" +z = x+y +r = z*3 # r is "RedBlackRedBlackRedBlack" +puts "values are #{x}, #{y}, #{z}, and #{r}" +print "#{x} is ", x < y ? "LT" : "GE", " #{y}\n" +# prints: +# values are Red, Black, RedBlack, and RedBlackRedBlackRedBlack +# Red is GE Black + +#----------------------------- +class FixNum + REGEX = /(\.\d*)/ + DEFAULT_PLACES = 0 + attr_accessor :value, :places + def initialize(value, places = nil) + @value = value + if places + @places = places + else + m = REGEX.match(value.to_s) + if m + @places = m[0].length - 1 + else + @places = DEFAULT_PLACES + end + end + end + + def +(other) + FixNum.new(@value + other.value, max(@places, other.places)) + end + + def *(other) + FixNum.new(@value * other.value, max(@places, other.places)) + end + + def /(other) + puts "Divide: #{@value.to_f/other.value.to_f}" + result = FixNum.new(@value.to_f/other.value.to_f) + result.places = max(result.places,other.places) + result + end + + def to_s + sprintf("STR%s: %.*f", self.class.to_s , @places, @value) #. + end + + def to_str + to_s + end + + def to_i #convert to int + @value.to_i + end + + def to_f #convert to float` + @value.to_f + end + + private + def max(a,b) + a > b ? a : b + end +end + +def demo() + x = FixNum.new(40) + y = FixNum.new(12, 0) + + puts "sum of #{x} and #{y} is #{x+y}" + puts "product of #{x} and #{y} is #{x*y}" + + z = x/y + puts "#{z} has #{z.places} places" + unless z.places + z.places = 2 + end + + puts "div of #{x} by #{y} is #{z}" + puts "square of that is #{z*z}" +end + +if __FILE__ == $0 + demo() +end + + +# @@PLEAC@@_14.1 +# There are dbm, sdbm, gdbm modules +# and the bdb module for accessing the berkeley db +# sdbm seem to be available on the most systems, +# so we use it here +# +require "sdbm" +SDBM.open("filename", 0666) { |dbobj| + # raises exception if open error + + # the returned sdbm-dbobj has most of the methods of a hash + v = dbobj["key"] + dbobj["key"] = "newvalue" + if dbobj.has_key?("key") + # ... + end + dbobj.delete("key2") +} +# database is open only inside the block. + +# It is also possible to use a open .. close pair: +dbobj = SDBM.open("filename", 0666) +#.. do something with dbobj +dbobj.close + +#!/usr/bin/ruby -w +# userstats - generate statistics on who is logged in +# call with usernames as argument to display the totals +# for the given usernames, call with "ALL" to display all users + +require "sdbm" +filename = '/tmp/userstats.db' +SDBM.open(filename, 0666) { |dbobj| + if ARGV.length > 0 + if ARGV[0] == "ALL" + # ARGV is constant, so we need the variable userlist + userlist = dbobj.keys().sort() + else + userlist = ARGV + end + userlist.each { |user| + print "#{user}\t#{dbobj[user]}\n" + } + else + who = `who` + who.split("\n").each { |line| + md = /^(\S+)/.match(line) + raise "Bad line from who: #{line}" unless md + # sdbm stores only strings, so "+=" doesn't work, + # we need to convert them expicitly back to integer. + if dbobj.has_key?(md[0]) + dbobj[md[0]] = dbobj[md[0]].to_i + 1 + else + dbobj[md[0]] = "1" + end + } + end +} + + +# @@PLEAC@@_14.2 +# using open and clear +dbobj = SDBM.open("filename", 0666) +dbobj.clear() +dbobj.close() +# deleting file and recreating it +# the filenames depend on the flavor of dbm you use, +# for example sdbm has two files named filename.pag and filename.dir, +# so you need to delete both files +begin + File.delete("filename") + # raises Exception if not exist + dbobj = SDBM.open("filename", 0666) +rescue + # add error handling here +end + + +# @@PLEAC@@_14.3 +# sdbm2gdbm: converts sdbm database to a gdbm database +require "sdbm" +require "gdbm" + +unless ARGV.length == 2 + fail "usage: sdbm2gdbm infile outfile" +end +infile = ARGV[0] +outfile = ARGV[1] + +sdb = SDBM.open(infile) +gdb = GDBM.open(outfile, 0666) +sdb.each { |key, val| + gdb[key] = val +} +gdb.close +sdb.close + + +# @@PLEAC@@_14.4 +#!/usr/bin/ruby -w +# dbmmerge: merges two dbm databases +require "sdbm" + +unless ARGV.length == 3 + fail "usage: dbmmerge indb1 indb2 outdb" +end +infile1 = ARGV[0] +infile2 = ARGV[0] +outfile = ARGV[2] + +in1 = SDBM.open(infile1, nil) +in2 = SDBM.open(infile2, nil) +outdb = SDBM.open(outfile, 0666) + +[in1, in2].each { |indb| + indb.each { |key, val| + if outdb.has_key?(key) + # decide which value to set. + # set outdb[key] if necessary + else + outdb[key] = val + end + } +} +in1.close +in2.close +outdb.close + + +# @@PLEAC@@_14.7 +# we write a tie method that extends the Array class. +# It reads the file into the memory, executes the code block +# in which you can manipulate the array as needed, and writes +# the array back to the file after the end of the block execution +class Array + def tie(filename, flags) + File.open(filename, flags) { |f| + f.each_line { |line| + self.push(line.chomp) + } + yield + f.rewind + each { |line| + if line + f.puts(line) + else + f.puts "" + end + } + } + end +end + +array = Array.new +array.tie("/tmp/textfile.txt", File::RDWR|File::CREAT) { + array[4] = "a new line 4" +} + +# The tied array can be manipulated like a normal array, +# so there is no need for a special API, and the recno_demo program +# to demonstrate is API is useless + + +# tied array demo: show how to use array with a tied file +filename = "db_file.txt" +lines = Array.new +File.unlink(filename) if File.exists?(filename) +lines.tie(filename, File::RDWR | File::CREAT) { + # first create a textfile to play with + lines[0] = "zero" + lines[1] = "one" + lines[2] = "two" + lines[3] = "three" + lines[4] = "four" + + # print the records in order. + # Opposed to perl, the tied array behaves exactly as a normal array + puts "\nOriginal" + for i in 0..(lines.length-1) + puts "#{i}: #{lines[i]}" + end + + #use push and pop + a = lines.pop + lines.push("last") + puts("The last line was [#{a}]") + + #use shift and unshift + a = lines.shift + lines.unshift("first") + puts("The first line was [#{a}]") + + # add record after record 2 + i = 2 + lines.insert(i + 1, "Newbie") + + # add record before record one + i = 1 + lines.insert(i, "New One") + + # delete record 3 + lines.delete_at(3) + + #now print the records in reverse order + puts "\nReverse" + (lines.length - 1).downto(0){ |i| + puts "#{i}: #{lines[i]}" + } + +} + + +# @@PLEAC@@_14.8 +# example to store complex data in a database +# uses marshall from the standard library +require "sdbm" +db = SDBM.open("pleac14-8-database", 0666) + +# convert the Objects into strings and back by using the Marshal module. +# Most normal objects can be converted out of the box, +# but not special things like procedure objects, +# IO instance variables, singleton objects + +db["Tom Christiansen"] = Marshal.dump(["book author", "tchrist@perl.com"]) +db["Tom Boutell"] = Marshal.dump(["shareware author", +"boutell@boutell.com"]) + +name1 = "Tom Christiansen" +name2 = "Tom Boutell" + +tom1 = Marshal.load(db[name1]) +tom2 = Marshal.load(db[name2]) + +puts "Two Toming: #{tom1} #{tom2}" + +if tom1[0] == tom2[0] && tom1[1] == tom2[1] + puts "You're having runtime fun with one Tom made two." +else + puts "No two Toms are ever alike" +end + +# To change parts of an entry, get the whole entry, change the parts, +# and save the whole entry back +entry = Marshal.load(db["Tom Boutell"]) +entry[0] = "Poet Programmer" +db["Tom Boutell"] = Marshal.dump(entry) +db.close + + +# @@PLEAC@@_14.9 +# example to make data persistent +# uses Marshal from the standard lib +# Stores the data in a simple file, +# see 14.8 on how to store it in a dbm file + +# The BEGIN block is executed before the rest of the script +# we use global variables here because local variables +# will go out of scope and are not accessible from the main script + +BEGIN { + $persistent_store = "persitence.dat" + begin + File.open($persistent_store) do |f| + $stringvariable1 = Marshal.load(f) + $arrayvariable2 = Marshal.load(f) + end + rescue + puts "Can not open #{$persistent_store}" + # Initialisation if this script runs the first time + $stringvariable1 = "" + $arrayvariable2 = [] + end +} + +END { + File.open($persistent_store, "w+") do |f| + Marshal.dump($stringvariable1, f) + Marshal.dump($arrayvariable2, f) + end +} + +# simple test program +puts $stringvariable1 +puts $arrayvariable2 +$stringvariable1 = "Hello World" +$arrayvariable2.push(5) +puts $stringvariable1 +puts $arrayvariable2 + + +# @@PLEAC@@_14.10 +#!/usr/bin/ruby -w +# Ruby has a dbi module with an architecture similar +# to the Perl dbi module: the dbi module provides an unified +# interface and uses specialized drivers for each dbms vendor +# +begin + DBI.connect("DBI:driver:driverspecific", "username", "auth") { + |dbh| + + dbh.do(SQL1) + + dbh.prepare(SQL2){ |sth| + sth.execute + sth.fetch {|row| + # ... + } + } # end of block finishes the statement handle + } # end of block closes the database connection +rescue DBI::DatabaseError => e + puts "dbi error occurred" + puts "Error code: #{e.err}" + puts "Error message: #{e.errstr}" +end + +#!/usr/bin/ruby -w +# dbusers - example for mysql which creates a table, +# fills it with values, retrieves the values back, +# and finally destroys the table. + +require "dbi" + +# replacement for the User::pwnt module +def getpwent + result = [] + File.open("/etc/passwd") {|file| + file.each_line {|line| + next if line.match(/^#/) + cols = line.split(":") + result.push([cols[2], cols[0]]) + } + } + result +end + +begin + DBI.connect("DBI:Mysql:pleacdatabase", "pleac", "pleacpassword") { + |conn| + + conn.do("CREATE TABLE users (uid INT, login CHAR(8))") + + users = getpwent + + conn.prepare("INSERT INTO users VALUES (?,?)") {|sth| + users.each {|entry| + sth.execute(entry[0], entry[1]) + } + } + + conn.execute("SELECT uid, login FROM users WHERE uid < 50") {|sth| + sth.fetch {|row| + puts row.collect {|col| + if col.nil? + "(null)" + else + col + end + }.join(", ") + } + } + + conn.do("DROP TABLE users") + } +rescue DBI::DatabaseError => e + puts "dbi error occurred" + puts "Error code: #{e.err}" + puts "Error message: #{e.errstr}" +end + + +# @@PLEAC@@_15.1 +# This test program demonstrates parsing program arguments. +# It uses the optparse library, which is included with ruby 1.8 +# It handles classic unix style and gnu style options +require 'optparse' + +@debugmode = false +@verbose = false + +ARGV.options do |opts| + opts.banner = "Usage: ruby #{$0} [OPTIONS] INPUTFILES" + + opts.on("-h", "--help", "show this message") { + puts opts + exit + } + # The OptionParser#on method is called with a specification of short + # options, of long options, a data type spezification and user help + # messages for this option. + # The method analyses the given parameter and decides what it is, + # so you can leave out the long option if you don't need it + opts.on("-v", "--[no-]verbose=[FLAG]", TrueClass, "run verbosly") { + |@verbose| # sets @verbose to true or false + } + opts.on("-D", "--DEBUG", TrueClass, "turns on debug mode" ){ + |@debugmode| # sets @debugmode to true + } + opts.on("-c", "--count=NUMBER", Integer, "how many times we do it" ){ + |@count| # sets @count to given integer + } + opts.on("-o", "--output=FILE", String, "file to write output to"){ + |@outputfile| # sets @outputfile to given string + } + opts.parse! +end + +# example to use the options in the main program +puts "Verbose is on" if @verbose +puts "Debugmode is on" if @debugmode +puts "Outfile is #{@outputfile}" if defined? @outputfile +puts "Count is #{@count}" if defined? @count +ARGV.each { |param| + puts "Got parameter #{param}" +} + + +# @@PLEAC@@_15.4 +buf = "\0" * 8 +$stdout.ioctl(0x5413, buf) +ws_row, ws_col, ws_xpixel, ws_ypixel = buf.unpack("S4") + +raise "You must have at least 20 characters" unless ws_col >= 20 +max = 0 +values = (1..5).collect { rand(20) } # generate an array[5] of rand values +for i in values + max = i if max < i +end +ratio = Float(ws_col-12)/max # chars per unit +for i in values + printf "%8.1f %s\n", i, "*" * (ratio*i) +end + +# gives, for example: +# 15.0 ******************************* +# 10.0 ********************* +# 5.0 ********** +# 14.0 ***************************** +# 18.0 ************************************** + + +# @@PLEAC@@_16.1 +output = `program args` # collect output into one multiline string +output = `program args`.split # collect output into array, one line per +element + +readme = IO.popen("ls") +output = "" +while readme.gets do + output += $_ +end +readme.close + +`fsck -y /dev/rsd1a` # BAD AND SCARY in Perl because it's managed by the shell + # I donna in Ruby ... + +# so the "clean and secure" version +readme, writeme = IO.pipe +pid = fork { + # child + $stdout = writeme + readme.close + exec('find', '..') +} +# parent +Process.waitpid(pid, 0) +writeme.close +while readme.gets do + # do something with $_ +end + + +# @@PLEAC@@_16.2 +status = system("xemacs #{myfile}") + +status = system("xemacs", myfile) + +system("cmd1 args | cmd2 | cmd3 >outfile") +system("cmd args <infile >outfile 2>errfile") + +# stop if the command fails +raise "$program exited funny: #{$?}" unless system("cmd", "args1", "args2") + +# get the value of the signal sent to the child +# even if it is a SIGINT or SIGQUIT +system(arglist) +raise "program killed by signal #{$?}" if ($? & 127) != 0 + +pid = fork { + trap("SIGINT", "IGNORE") + exec("sleep", "10") +} +trap ("SIGINT") { + puts "Tsk tsk, no process interruptus" +} +Process.waitpid(pid, 0) + +# Ruby doesn't permit to lie to the program called by a 'system'. +# (ie specify what return argv[0] in C, $0 in Perl/Ruby ...) +# A (dirty) way is to create a link (under Unix), run this link and +# erase it. Somebody has a best idea ? + + +# @@PLEAC@@_16.3 +exec("archive *.data") + +exec("archive", "accounting.data") + +exec("archive accounting.data") + + +# @@PLEAC@@_16.4 +# read the output of a program +IO.popen("ls") {|readme| + while readme.gets do + # ... + end +} +# or +readme = IO.popen("ls") +while readme.gets do + # ... +end +readme.close + +# "write" in a program +IO.popen("cmd args","w") {|pipe| + pipe.puts("data") + pipe.puts("foo") +} + +# close wait for the end of the process +read = IO.popen("sleep 10000") # child goes to sleep +read.close # and the parent goes to lala land + +writeme = IO.popen("cmd args", "w") +writeme.puts "hello" # program will get hello\n on STDIN +writeme.close # program will get EOF on STDIN + +# send in a pager (eg less) all output +$stdout = IO.popen("/usr/bin/less","w") +print "huge string\n" * 10000 + + +# @@PLEAC@@_16.5 +#----------------------------- +def head(lines = 20) + pid = open("|-","w") + if pid == nil + return + else + while gets() do + pid.print + lines -= 1 + break if lines == 0 + end + end + exit +end + +head(100) +while gets() do + print +end +#----------------------------- +1: > Welcome to Linux, version 2.0.33 on a i686 + +2: > + +3: > "The software required `Windows 95 or better', + +4: > so I installed Linux." +#----------------------------- +> 1: Welcome to Linux, Kernel version 2.0.33 on a i686 + +> 2: + +> 3: "The software required `Windows 95 or better', + +> 4: so I installed Linux." +#----------------------------- +#!/usr/bin/ruby +# qnumcat - demo additive output filters + +def number() + pid = open("|-","w") + if pid == nil + return + else + while gets() do pid.printf("%d: %s", $., $_); end + end + exit +end + +def quote() + pid = open("|-","w") + if pid == nil + return + else + while gets() do pid.print "> #{$_}" end + end + exit +end + +number() +quote() + +while gets() do + print +end +$stdout.close +exit + + +# @@PLEAC@@_16.6 +ARGV.map! { |arg| + arg =~ /\.(gz|Z)$/ ? "|gzip -dc #{arg}" : arg +} +for file in ARGV + fh = open(file) + while fh.gets() do + # ....... + end +end +#----------------------------- +ARGV.map! { |arg| + arg =~ %r#^\w+://# ? "|GET #{arg}" : arg # +} +for file in ARGV + fh = open(file) + while fh.gets() do + # ....... + end +end +#----------------------------- +pwdinfo = (`domainname` =~ /^(\(none\))?$/) ? '/etc/passwd' : '|ypcat passwd'; +pwd = open(pwdinfo); +#----------------------------- +puts "File, please? "; +file = gets().chomp(); +fh = open(file); + + +# @@PLEAC@@_16.7 +output = `cmd 2>&1` # with backticks +# or +ph = open("|cmd 2>&1") # with an open pipe +while ph.gets() { } # plus a read +#----------------------------- +output = `cmd 2>/dev/null` # with backticks +# or +ph = open("|cmd 2>/dev/null") # with an open pipe +while ph.gets() { } # plus a read +#----------------------------- +output = `cmd 2>&1 1>/dev/null` # with backticks +# or +ph = open("|cmd 2>&1 1>/dev/null") # with an open pipe +while ph.gets() { } # plus a read +#----------------------------- +output = `cmd 3>&1 1>&2 2>&3 3>&-` # with backticks +# or +ph = open("|cmd 3>&1 1>&2 2>&3 3>&-") # with an open pipe +while ph.gets() { } # plus a read +#----------------------------- +system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr") +#----------------------------- +output = `cmd 3>&1 1>&2 2>&3 3>&-` +#----------------------------- +fd3 = fd1 +fd1 = fd2 +fd2 = fd3 +fd3 = nil +#----------------------------- +system("prog args 1>tmpfile 2>&1") +system("prog args 2>&1 1>tmpfile") +#----------------------------- +# system ("prog args 1>tmpfile 2>&1") +fd1 = "tmpfile" # change stdout destination first +fd2 = fd1 # now point stderr there, too +#----------------------------- +# system("prog args 2>&1 1>tmpfile") +fd2 = fd1 # stderr same destination as stdout +fd1 = "tmpfile" # but change stdout destination +#----------------------------- +# It is often better not to rely on the shell, +# because of portability, possible security problems +# and bigger resource usage. So, it is often better to use the open3 library. +# See below for an example. +# opening stdin, stdout, stderr +require "open3" +stdin, stdout, stderr = Open3.popen('cmd') + + +# @@PLEAC@@_16.8 +#----------------------------- +# Contrary to perl, we don't need to use a module in Ruby +fh = Kernel.open("|" + program, "w+") +fh.puts "here's your input\n" +output = fh.gets() +fh.close() +#----------------------------- +Kernel.open("|program"),"w+") # RIGHT ! +#----------------------------- +# Ruby has already object methods for I/O handles +#----------------------------- +begin + fh = Kernel.open("|" + program_and_options, "w+") +rescue + if ($@ ~= /^open/) + $stderr.puts "open failed : #{$!} \n #{$@} \n" + break + end + raise # reraise unforseen exception +end + + +# @@PLEAC@@_16.13 +#% kill -l +#HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE +#ALRM TERM CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM +#PROF WINCH POLL PWR +#----------------------------- +#% ruby -e 'puts Signal.list.keys.join(" ")' +#PWR USR1 BUS USR2 TERM SEGV KILL POLL STOP SYS TRAP IOT HUP INT # +#WINCH XCPU TTIN CLD TSTP FPE IO TTOU PROF CHLD CONT PIPE ABRT +#VTALRM QUIT ILL XFSZ URG ALRM +#----------------------------- +# After that, the perl script create an hash equivalent to Signal.list, +# and an array. The array can be obtained by : +signame = [] +Signal.list.each { |name, i| signame[i] = name } + + +# @@PLEAC@@_16.14 +Process.kill(9, pid) # send $pid a signal 9 +Process.kill(-1, Process.getpgrp()) # send whole job a signal 1 +Process.kill("USR1", $$) # send myself a SIGUSR1 +Process.kill("HUP", pid1, pid2, pid3) # send a SIGHUP to processes in @pids +#----------------------------- +begin + Process.kill(0, minion) + puts "#{minion} is alive!" +rescue Errno::EPERM # changed uid + puts "#{minion} has escaped my control!"; +rescue Errno::ESRCH + puts "#{minion} is deceased."; # or zombied +rescue + puts "Odd; I couldn't check the status of #{minion} : #{$!}" +end + + +# @@PLEAC@@_16.15 +Kernel.trap("QUIT", got_sig_quit) # got_sig_quit = Proc.new { puts "Quit\n" } +trap("PIPE", "got_sig_quit") # def got_sig_pipe ... +trap("INT") { ouch++ } # increment ouch for every SIGINT +#----------------------------- +trap("INT", "IGNORE") # ignore the signal INT +#----------------------------- +trap("STOP", "DEFAULT") # restore default STOP signal handling + + +# @@PLEAC@@_16.16 +# the signal handler +def ding + trap("INT", "ding") + puts "\aEnter your name!" +end + +# prompt for name, overriding SIGINT +def get_name + save = trap("INT", "ding") + + puts "Kindly Stranger, please enter your name: " + name = gets().chomp() + trap("INT", save) + name +end + + +# @@PLEAC@@_16.21 +# implemented thanks to http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/1760 +require 'timeout' + +# we'll do something vastly more useful than cookbook to demonstrate timeouts +begin + timeout(5) { + waitsec = rand(10) + puts "Let's see if a sleep of #{waitsec} seconds is longer than 5 seconds..." + system("sleep #{waitsec}") + } + puts "Timeout didn't occur" +rescue Timeout::Error + puts "Timed out!" +end + + +# @@PLEAC@@_17.1 +# A basic TCP client connection +require 'socket' +begin + t = TCPSocket.new('www.ruby-lang.org', 'www') +rescue + puts "error: #{$!}" +else + # ... do something with the socket + t.print "GET / HTTP/1.0\n\n" + answer = t.gets(nil) + # and terminate the connection when we're done + t.close +end + +# Using the evil low level socket API +require 'socket' +# create a socket +s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) +# build the address of the remote machine +sockaddr_server = [Socket::AF_INET, 80, + Socket.gethostbyname('www.ruby-lang.org')[3], + 0, 0].pack("snA4NN") +# connect +begin + s.connect(sockaddr_server) +rescue + puts "error: #{$!}" +else + # ... do something with the socket + s.print "GET / HTTP/1.0\n\n" + # and terminate the connection when we're done + s.close +end + +# TCP connection with management of error (DNS) +require 'socket' +begin + client = TCPSocket.new('does not exists', 'www') +rescue + puts "error: #{$!}" +end + +# TCP connection with a time out +require 'socket' +require 'timeout' +begin + timeout(1) do #the server has one second to answer + client = TCPSocket.new('www.host.com', 'www') + end +rescue + puts "error: #{$!}" +end + + +# @@PLEAC@@_17.12 +require 'socket' + +class Preforker + attr_reader (:child_count) + + def initialize(prefork, max_clients_per_child, port, client_handler) + @prefork = prefork + @max_clients_per_child = max_clients_per_child + @port = port + @child_count = 0 + + @reaper = proc { + trap('CHLD', @reaper) + pid = Process.wait + @child_count -= 1 + } + + @huntsman = proc { + trap('CHLD', 'IGNORE') + trap('INT', 'IGNORE') + Process.kill('INT', 0) + exit + } + + @client_handler=client_handler + end + + def child_handler + trap('INT', 'EXIT') + @client_handler.setUp + # wish: sigprocmask UNblock SIGINT + @max_clients_per_child.times { + client = @server.accept or break + @client_handler.handle_request(client) + client.close + } + @client_handler.tearDown + end + + def make_new_child + # wish: sigprocmask block SIGINT + @child_count += 1 + pid = fork do + child_handler + end + # wish: sigprocmask UNblock SIGINT + end + + def run + @server = TCPserver.open(@port) + trap('CHLD', @reaper) + trap('INT', @huntsman) + loop { + (@prefork - @child_count).times { |i| + make_new_child + } + sleep .1 + } + end +end + +#----------------------------- +#!/usr/bin/ruby + +require 'Preforker' + +class ClientHandler + def setUp + end + + def tearDown + end + + def handle_request(client) + # do stuff + end +end + +server = Preforker.new(1, 100, 3102, ClientHandler.new) +server.run + + +# @@PLEAC@@_18.2 +require 'net/ftp' + +begin + ftp = Net::FTP::new("ftp.host.com") + ftp.login(username,password) + ftp.chdir(directory) + ftp.get(filename) + ftp.put(filename) +rescue Net::FTPError + $stderr.print "FTP failed: " + $! +ensure + ftp.close() if ftp +end + +# A better solution for a local use could be : +Net::FTP::new("ftp.host.com") do |ftp| + ftp.login(username,password) + ftp.chdir(directory) + ftp.get(filename) + ftp.put(filename) +end + +# If you have only one file to get, there is a simple solution : +require 'open-uri' +open("ftp://www.ruby-lang.org/path/filename") do |fh| + # read from filehandle fh +end +#-------------------------------------------- +# to wait a defined time for the connection, +# use the timeout module +require 'timeout' +begin + timeout(30){ + ftp = Net::FTP::new("ftp.host.com") + ftp.debug_mode = true + } +rescue Net::FTPError + $stderr.puts "Couldn't connect." +rescue Timeout::Error + $stderr.puts "Timeout while connecting to server." +end + +begin + ftp.login() +rescue Net::FTPError + $stderr.print "Couldn't authentificate.\n" +end + +begin + ftp.login(username) +rescue Net::FTPError + $stderr.print "Still couldn't authenticate.\n" +end + +begin + ftp.login(username, password) +rescue Net::FTPError + $stderr.print "Couldn't authenticate, even with explicit + username and password.\n" +end + +begin + ftp.login(username, password, account) +rescue Net::FTPError + $stderr.print "No dice. It hates me.\n" +end +#----------------------------- +ftp.put(localfile, remotefile) +#----------------------------- +# Sending data from STDIN is not directly supported +# by the ftp library module. A possible way to do it is to use the +# storlines method directly to send raw commands to the ftp server. +#----------------------------- +ftp.get(remotefile, localfile) +#----------------------------- +ftp.get(remotefile) { |data| puts data } +#----------------------------- +ftp.chdir("/pub/ruby") +print "I'm in the directory ", ftp.pwd(), "\n" +#----------------------------- +ftp.mkdir("/pub/ruby/new_dir") +#----------------------------- +lines = ftp.ls("/pub/ruby/") +# => ["drwxr-xr-x 2 matz users 4096 July 17 1998 1.0", ... ] + +latest = ftp.dir("/pub/ruby/*.tgz").sort.last + +ftp.nlst("/pub/ruby") +# => ["/pub/ruby/1.0", ... ] +#----------------------------- +ftp.quit() + + +# @@PLEAC@@_18.6 +require 'net/telnet' +t = Net::Telnet::new( "Timeout" => 10, + "Prompt" => /%/, + "Host" => host ) +t.login(username, password) +files = t.cmd("ls") +t.print("top") +process_string = t.waitfor(/\d+ processes/) +t.close +#----------------------------- +/[$%#>] \z/n +#----------------------------- +# In case of an error, the telnet module throws an exception. +# For control of the behavior in case of an error, +# you just need to catch the exceptions and do your custom +# error handling. +#----------------------------- +begin + telnet.login(username, password) +rescue TimeoutError + fail "Login failed !\n" +end +#----------------------------- +telnet.waitfor('/--more--/') +#----------------------------- +telnet.waitfor(String => 'greasy smoke', Timeout => 30) + + +# @@PLEAC@@_18.7 +require 'ping' + +puts "#{host} is alive.\n" if Ping.pingecho(host); +#----------------------------- +# the ping module only use TCP ping, not ICMP even if we are root +if Ping.pingecho("kingkong.com") + puts "The giant ape lives!\n"; +else + puts "All hail mighty Gamera, friend of children!\n"; +end + + +# @@PLEAC@@_19.0 +#----------------------------- +# http://www.perl.com/CPAN/ +# http://www.perl.com:8001/bad/mojo.html +# ftp://gatekeeper.dec.com/pub/misc/netlib.tar.Z +# ftp://anonymous@myplace:gatekeeper.dec.com/pub/misc/netlib.tar.Z +# file:///etc/motd +#----------------------------- +# http://mox.perl.com/cgi-bin/program?name=Johann&born=1685 +#----------------------------- +# http://mox.perl.com/cgi-bin/program +#----------------------------- + + +# @@PLEAC@@_19.1 +#!/usr/local/bin/ruby -w +# hiweb - load CGI class to decode information given by web server + +require 'cgi' + +cgi = CGI.new('html3') + +# get a parameter from a form +value = cgi.params['PARAM_NAME'][0] + +# output a document +cgi.out { + cgi.html { + cgi.head { cgi.title { "Howdy there!" } } + + cgi.body { cgi.p { "You typed: " + cgi.tt { + CGI.escapeHTML(value) } } } + } +} + +require 'cgi' +cgi = CGI.new +who = cgi.param["Name"][0] # first param in list +phone = cgi.param["Number"][0] +picks = cgi.param["Choices"] # complete list + +print cgi.header( 'type' => 'text/plain', + 'expires' => Time.now + (3 * 24 * 60 * 60) ) + + +# @@PLEAC@@_19.3 +#!/usr/local/bin/ruby -w +# webwhoami - show web user's id +require 'etc' +print "Content-Type: text/plain\n\n" +print "Running as " + Etc.getpwuid.name + "\n" + +# % ruby -wc cgi-script # just check syntax + +# % ruby -w cgi-script # params from stdin +# (offline mode: enter name=value pairs on standard input) +# name=joe +# number=10 +# ^D + +# % ruby -w cgi-script name=joe number=10 # run with mock form input +# % ruby -d cgi-script name=joe number=10 # ditto, under the debugger + +# POST method script in csh +# % (setenv HTTP_METHOD POST; ruby -w cgi-script name=joe number=10) +# POST method script in sh +# % HTTP_METHOD=POST perl -w cgi-script name=joe number=10 + + +# @@PLEAC@@_19.4 +# ruby has several security levels, the level "1" is similar to perls taint mode. +# It can be switched on by providing the -T command line parameter +# or by setting $SAFE to 1. Setting $SAFE to 2,3 or 4 restricts possible +# harmful operations further. + +#!/usr/bin/ruby -T +$SAFE = 1 +File.open(ARGV[0], "w") +# ruby warns with: +# taint1.rb:2:in `initialize': Insecure operation - initialize (SecurityError) + +$SAFE = 1 +file = ARGV[0] +unless /^([\w.-]+)$/.match(file) + raise "filename #{file} has invalid characters" +end +file = $1 +# In ruby, even the back reference from a regular expression stays tainted. +# you need to explicitly untaint the variable: +file.untaint +File.open(file, "w") + +# Race condition exists like in perl: +unless File.exists(filename) # Wrong because of race condition + File.open(filename, "w") +end + + +# @@PLEAC@@_19.8 +url = "http://pleac.sourceforge.net/pleac_ruby/" +print "Location: #{url}\r\n\r\n" +exit + +#!/usr/bin/ruby +require 'cgi' + +cgi = CGI.new +oreo = CGI::Cookie.new('name' => 'filling', + 'value' => 'vanilla creme', + 'expires' => Time.now + (3 * 30 * 24 * 60 * 60), + 'domain' => '.pleac.sourceforge.net') + +whither = 'http://pleac.sourceforge.net/pleac_ruby/cgiprogramming.html' + +cgi.out('cookie' => oreo, + 'Location' => whither){""} + +#!/usr/bin/ruby +# os_snipe - redirect to a Jargon File entry about current OS +dir = 'http://www.elsewhere.org/jargon/html/entry' + +agent = ENV['HTTP_USER_AGENT'] + +page = case + when agent =~ /Mac/: 'Macintrash.html' + when agent =~ /Win(dows )?NT/: 'evil_and_rude.html' + when agent =~ /Win|MSIE|WebTV/: 'Microsloth_Windows.html' + when agent =~ /Linux/: 'Linux.html' + when agent =~ /HP-UX/: 'HP-SUX.html' + when agent =~ /SunOS/: 'ScumOS.html' + else 'Appendix_B.html' +end + +print "Location: #{dir}/#{page}\n\n" + +require 'cgi' +cgi = CGI.new +cgi.out('status' => '204 No response'){""} +# this produces: +# Status: 204 No response +# Content-Type: text/html +# Content-Length: 0 +# <blank line here> + + +# @@PLEAC@@_19.10 +preference_value = cgi.cookies["preference name"][0] + +packed_cookie = CGI::Cookie.new("name" => "preference name", + "value" => "whatever you'd like", + "expires" => Time.local(Time.now.year + 2, + Time.now.mon, Time.now.day, Time.now.hour, Time.now.min, Time.now.sec) ) + +cgi.header("cookie" => [packed_cookie]) + +#!/usr/local/bin/ruby -w +# ic_cookies - sample CGI script that uses a cookie +require 'cgi' + +cgi = CGI.new('html3') + +cookname = "favorite ice cream" +favorite = cgi.params["flavor"][0] +tasty = cgi.cookies[cookname][0] || 'mint' + +unless favorite + cgi.out { + cgi.html { + cgi.head { cgi.title { "Ice Cookies" } } + + cgi.body { + cgi.h1 { "Hello Ice Cream" } + + cgi.hr + + cgi.form { + cgi.p { "Please select a flavor: " + + cgi.text_field("flavor", tasty ) } + } + + cgi.hr + } + } + } +else + cookie = CGI::Cookie.new( "name" => cookname, + "value" => favorite, + "expires" => Time.local(Time.now.year + 2, +Time.now.mon, Time.now.day, Time.now.hour, Time.now.min, Time.now.sec) ) + cgi.out("cookie" => [cookie]) { + cgi.html { + cgi.head { cgi.title { "Ice Cookies" } } + + cgi.body { + cgi.h1 { "Hello Ice Cream" } + + cgi.p { "You chose as your favorite flavor `#{favorite}'." } + } + } + } +end + + +# @@PLEAC@@_20.9 +def templatefile(filename, fillings) + aFile = File.new(filename, "r") + text = aFile.read() + aFile.close() + pattern = Regexp.new('%%(.*?)%%') + text.gsub!(pattern) { + fillings[$1] || "" + } + text +end + +fields = { + 'username' => whats_his_name, + 'count' => login_count, + 'total' => minutes_used +} +puts templatefile('simple.template', fields) + +# @@INCOMPLETE@@ +# An example using databases is missing + + diff --git a/test/ruby/pleac.out.raydebug b/test/ruby/pleac.out.raydebug new file mode 100644 index 0000000..571d66e --- /dev/null +++ b/test/ruby/pleac.out.raydebug @@ -0,0 +1,6368 @@ +comment(# -*- ruby -*-)
+
+comment(# Local variables:)
+comment(# indent-tabs-mode: nil)
+comment(# ruby-indent-level: 4)
+comment(# End:)
+
+comment(# @@PLEAC@@_NAME)
+comment(# @@SKIP@@ Ruby)
+
+comment(# @@PLEAC@@_WEB)
+comment(# @@SKIP@@ http://www.ruby-lang.org)
+
+
+comment(# @@PLEAC@@_1.0)
+ident(string) operator(=) string<delimiter(')content(\\n)delimiter(')> comment(# two characters, \\ and an n)
+ident(string) operator(=) string<delimiter(')content(Jon )char(\\')content(Maddog)char(\\')content( Orwant)delimiter(')> comment(# literal single quotes)
+
+ident(string) operator(=) string<delimiter(")char(\\n)delimiter(")> comment(# a "newline" character)
+ident(string) operator(=) string<delimiter(")content(Jon )char(\\")content(Maddog)char(\\")content( Orwant)delimiter(")> comment(# literal double quotes)
+
+ident(string) operator(=) string<delimiter(%q/)content(Jon 'Maddog' Orwant)delimiter(/)> comment(# literal single quotes)
+
+ident(string) operator(=) string<delimiter(%q[)content(Jon 'Maddog' Orwant)delimiter(])> comment(# literal single quotes)
+ident(string) operator(=) string<delimiter(%q{)content(Jon 'Maddog' Orwant)delimiter(})> comment(# literal single quotes)
+ident(string) operator(=) string<delimiter(%q()content(Jon 'Maddog' Orwant)delimiter(\))> comment(# literal single quotes)
+ident(string) operator(=) string<delimiter(%q<)content(Jon 'Maddog' Orwant)delimiter(>)> comment(# literal single quotes)
+
+ident(a) operator(=) string<delimiter(<<"EOF")>string<content(
+This is a multiline here document
+terminated by EOF on a line by itself)delimiter(
+EOF)>
+
+
+comment(# @@PLEAC@@_1.1)
+ident(value) operator(=) ident(string)operator([)ident(offset)operator(,)ident(count)operator(])
+ident(value) operator(=) ident(string)operator([)ident(offset)operator(..)operator(-)integer(1)operator(])
+
+ident(string)operator([)ident(offset)operator(,)ident(count)operator(]) operator(=) ident(newstring)
+ident(string)operator([)ident(offset)operator(..)operator(-)integer(1)operator(]) operator(=) ident(newtail)
+
+comment(# in Ruby we can also specify intervals by their two offsets)
+ident(value) operator(=) ident(string)operator([)ident(offset)operator(..)ident(offs2)operator(])
+ident(string)operator([)ident(offset)operator(..)ident(offs2)operator(]) operator(=) ident(newstring)
+
+ident(leading)operator(,) ident(s1)operator(,) ident(s2)operator(,) ident(trailing) operator(=) ident(data)operator(.)ident(unpack)operator(()string<delimiter(")content(A5 x3 A8 A8 A*)delimiter(")>operator(\))
+
+ident(fivers) operator(=) ident(string)operator(.)ident(unpack)operator(()string<delimiter(")content(A5)delimiter(")> operator(*) operator(()ident(string)operator(.)ident(length)operator(/)integer(5)operator(\))operator(\))
+
+ident(chars) operator(=) ident(string)operator(.)ident(unpack)operator(()string<delimiter(")content(A1)delimiter(")> operator(*) ident(string)operator(.)ident(length)operator(\))
+
+ident(string) operator(=) string<delimiter(")content(This is what you have)delimiter(")>
+comment(# +012345678901234567890 Indexing forwards (left to right\))
+comment(# 109876543210987654321- Indexing backwards (right to left\))
+comment(# note that 0 means 10 or 20, etc. above)
+
+ident(first) operator(=) ident(string)operator([)integer(0)operator(,) integer(1)operator(]) comment(# "T")
+ident(start) operator(=) ident(string)operator([)integer(5)operator(,) integer(2)operator(]) comment(# "is")
+ident(rest) operator(=) ident(string)operator([)integer(13)operator(..)operator(-)integer(1)operator(]) comment(# "you have")
+ident(last) operator(=) ident(string)operator([)operator(-)integer(1)operator(,) integer(1)operator(]) comment(# "e")
+ident(end_) operator(=) ident(string)operator([)operator(-)integer(4)operator(..)operator(-)integer(1)operator(]) comment(# "have")
+ident(piece) operator(=) ident(string)operator([)operator(-)integer(8)operator(,) integer(3)operator(]) comment(# "you")
+
+ident(string)operator([)integer(5)operator(,) integer(2)operator(]) operator(=) string<delimiter(")content(wasn't)delimiter(")> comment(# change "is" to "wasn't")
+ident(string)operator([)operator(-)integer(12)operator(..)operator(-)integer(1)operator(]) operator(=) string<delimiter(")content(ondrous)delimiter(")> comment(# "This wasn't wondrous")
+ident(string)operator([)integer(0)operator(,) integer(1)operator(]) operator(=) string<delimiter(")delimiter(")> comment(# delete first character)
+ident(string)operator([)operator(-)integer(10)operator(..)operator(-)integer(1)operator(]) operator(=) string<delimiter(")delimiter(")> comment(# delete last 10 characters)
+
+reserved(if) ident(string)operator([)operator(-)integer(10)operator(..)operator(-)integer(1)operator(]) operator(=)operator(~) regexp<delimiter(/)content(pattern)delimiter(/)>
+ ident(puts) string<delimiter(")content(Pattern matches in last 10 characters)delimiter(")>
+reserved(end)
+
+ident(string)operator([)integer(0)operator(,) integer(5)operator(])operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(is)delimiter(/)>operator(,) string<delimiter(')content(at)delimiter(')>operator(\))
+
+ident(a) operator(=) string<delimiter(")content(make a hat)delimiter(")>
+ident(a)operator([)integer(0)operator(,) integer(1)operator(])operator(,) ident(a)operator([)operator(-)integer(1)operator(,) integer(1)operator(]) operator(=) ident(a)operator([)operator(-)integer(1)operator(,) integer(1)operator(])operator(,) ident(a)operator([)integer(0)operator(,) integer(1)operator(])
+
+ident(a) operator(=) string<delimiter(")content(To be or not to be)delimiter(")>
+ident(b) operator(=) ident(a)operator(.)ident(unpack)operator(()string<delimiter(")content(x6 A6)delimiter(")>operator(\))
+
+ident(b)operator(,) ident(c) operator(=) ident(a)operator(.)ident(unpack)operator(()string<delimiter(")content(x6 A2 X5 A2)delimiter(")>operator(\))
+ident(puts) string<delimiter(")inline<delimiter(#{)ident(b)delimiter(})>char(\\n)inline<delimiter(#{)ident(c)delimiter(})>char(\\n)delimiter(")>
+
+reserved(def) method(cut2fmt)operator(()operator(*)ident(args)operator(\))
+ ident(template) operator(=) string<delimiter(')delimiter(')>
+ ident(lastpos) operator(=) integer(1)
+ reserved(for) ident(place) reserved(in) ident(args)
+ ident(template) operator(+)operator(=) string<delimiter(")content(A)delimiter(")> operator(+) operator(()ident(place) operator(-) ident(lastpos)operator(\))operator(.)ident(to_s) operator(+) string<delimiter(")content( )delimiter(")>
+ ident(lastpos) operator(=) ident(place)
+ reserved(end)
+ ident(template) operator(+)operator(=) string<delimiter(")content(A*)delimiter(")>
+ reserved(return) ident(template)
+reserved(end)
+
+ident(fmt) operator(=) ident(cut2fmt)operator(()integer(8)operator(,) integer(14)operator(,) integer(20)operator(,) integer(26)operator(,) integer(30)operator(\))
+
+
+comment(# @@PLEAC@@_1.2)
+comment(# careful! "b is true" doesn't mean "b != 0" (0 is true in Ruby\))
+comment(# thus no problem of "defined" later since only nil is false)
+comment(# the following sets to `c' if `b' is nil or false)
+ident(a) operator(=) ident(b) operator(||) ident(c)
+
+comment(# if you need Perl's behaviour (setting to `c' if `b' is 0\) the most)
+comment(# effective way is to use Numeric#nonzero? (thanks to Dave Thomas!\))
+ident(a) operator(=) ident(b)operator(.)ident(nonzero?) operator(||) ident(c)
+
+comment(# you will still want to use defined? in order to test)
+comment(# for scope existence of a given object)
+ident(a) operator(=) reserved(defined?)operator(()ident(b)operator(\)) operator(?) ident(b) operator(:) ident(c)
+
+ident(dir) operator(=) pre_constant(ARGV)operator(.)ident(shift) operator(||) string<delimiter(")content(/tmp)delimiter(")>
+
+
+comment(# @@PLEAC@@_1.3)
+ident(v1)operator(,) ident(v2) operator(=) ident(v2)operator(,) ident(v1)
+
+ident(alpha)operator(,) ident(beta)operator(,) ident(production) operator(=) string<delimiter(%w()content(January March August)delimiter(\))>
+ident(alpha)operator(,) ident(beta)operator(,) ident(production) operator(=) ident(beta)operator(,) ident(production)operator(,) ident(alpha)
+
+
+comment(# @@PLEAC@@_1.4)
+ident(num) operator(=) ident(char)operator([)integer(0)operator(])
+ident(char) operator(=) ident(num)operator(.)ident(chr)
+
+comment(# Ruby also supports having a char from character constant)
+ident(num) operator(=) integer(?r)
+
+ident(char) operator(=) ident(sprintf)operator(()string<delimiter(")content(%c)delimiter(")>operator(,) ident(num)operator(\))
+ident(printf)operator(()string<delimiter(")content(Number %d is character %c)char(\\n)delimiter(")>operator(,) ident(num)operator(,) ident(num)operator(\))
+
+ident(ascii) operator(=) ident(string)operator(.)ident(unpack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+ident(string) operator(=) ident(ascii)operator(.)ident(pack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+
+ident(hal) operator(=) string<delimiter(")content(HAL)delimiter(")>
+ident(ascii) operator(=) ident(hal)operator(.)ident(unpack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+comment(# We can't use Array#each since we can't mutate a Fixnum)
+ident(ascii)operator(.)ident(collect!) operator({) operator(|)ident(i)operator(|)
+ ident(i) operator(+) integer(1) comment(# add one to each ASCII value)
+operator(})
+ident(ibm) operator(=) ident(ascii)operator(.)ident(pack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+ident(puts) ident(ibm)
+
+
+comment(# @@PLEAC@@_1.5)
+ident(array) operator(=) ident(string)operator(.)ident(split)operator(()string<delimiter(')delimiter(')>operator(\))
+
+ident(array) operator(=) ident(string)operator(.)ident(unpack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+
+ident(string)operator(.)ident(scan)operator(()regexp<delimiter(/)content(.)delimiter(/)>operator(\)) operator({) operator(|)ident(b)operator(|)
+ comment(# do something with b)
+operator(})
+
+ident(string) operator(=) string<delimiter(")content(an apple a day)delimiter(")>
+ident(print) string<delimiter(")content(unique chars are: )delimiter(")>operator(,) ident(string)operator(.)ident(split)operator(()string<delimiter(')delimiter(')>operator(\))operator(.)ident(uniq)operator(.)ident(sort)operator(,) string<delimiter(")char(\\n)delimiter(")>
+
+ident(sum) operator(=) integer(0)
+reserved(for) ident(ascval) reserved(in) ident(string)operator(.)ident(unpack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\)) comment(# or use Array#each for a pure OO style :\))
+ ident(sum) operator(+)operator(=) ident(ascval)
+reserved(end)
+ident(puts) string<delimiter(")content(sum is )inline<delimiter(#{)ident(sum) operator(&) integer(0xffffffff)delimiter(})>delimiter(")> comment(# since Ruby will go Bignum if necessary)
+
+comment(# @@INCLUDE@@ include/ruby/slowcat.rb)
+
+
+comment(# @@PLEAC@@_1.6)
+ident(revbytes) operator(=) ident(string)operator(.)ident(reverse)
+
+ident(revwords) operator(=) ident(string)operator(.)ident(split)operator(()string<delimiter(")content( )delimiter(")>operator(\))operator(.)ident(reverse)operator(.)ident(join)operator(()string<delimiter(")content( )delimiter(")>operator(\))
+
+ident(revwords) operator(=) ident(string)operator(.)ident(split)operator(()regexp<delimiter(/)content(()char(\\s)content(+\))delimiter(/)>operator(\))operator(.)ident(reverse)operator(.)ident(join)
+
+comment(# using the fact that IO is Enumerable, you can directly "select" it)
+ident(long_palindromes) operator(=) constant(File)operator(.)ident(open)operator(()string<delimiter(")content(/usr/share/dict/words)delimiter(")>operator(\))operator(.)
+ ident(select) operator({) operator(|)ident(w)operator(|) ident(w)operator(.)ident(chomp!)operator(;) ident(w)operator(.)ident(reverse) operator(==) ident(w) operator(&&) ident(w)operator(.)ident(length) operator(>) integer(5) operator(})
+
+
+comment(# @@PLEAC@@_1.7)
+reserved(while) ident(string)operator(.)ident(sub!)operator(()string<delimiter(")char(\\t)content(+)delimiter(")>operator(\)) operator({) string<delimiter(')content( )delimiter(')> operator(*) operator(()global_variable($&)operator(.)ident(length) operator(*) integer(8) operator(-) global_variable($`)operator(.)ident(length) operator(%) integer(8)operator(\)) operator(})
+reserved(end)
+
+
+comment(# @@PLEAC@@_1.8)
+string<delimiter(')content(You owe #{debt} to me)delimiter(')>operator(.)ident(gsub)operator(()regexp<delimiter(/)char(\\#)content({()char(\\w)content(+\)})delimiter(/)>operator(\)) operator({) ident(eval)operator(()global_variable($1)operator(\)) operator(})
+
+ident(rows)operator(,) ident(cols) operator(=) integer(24)operator(,) integer(80)
+ident(text) operator(=) string<delimiter(%q()content(I am #{rows} high and #{cols} long)delimiter(\))>
+ident(text)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\#)content({()char(\\w)content(+\)})delimiter(/)>operator(\)) operator({) ident(eval)operator(()string<delimiter(")inline<delimiter(#{)global_variable($1)delimiter(})>delimiter(")>operator(\)) operator(})
+ident(puts) ident(text)
+
+string<delimiter(')content(I am 17 years old)delimiter(')>operator(.)ident(gsub)operator(()regexp<delimiter(/)char(\\d)content(+)delimiter(/)>operator(\)) operator({) integer(2) operator(*) global_variable($&)operator(.)ident(to_i) operator(})
+
+
+comment(# @@PLEAC@@_1.9)
+ident(e) operator(=) string<delimiter(")content(bo peep)delimiter(")>operator(.)ident(upcase)
+ident(e)operator(.)ident(downcase!)
+ident(e)operator(.)ident(capitalize!)
+
+string<delimiter(")content(thIS is a loNG liNE)delimiter(")>operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\w)content(+)delimiter(/)>operator(\)) operator({) global_variable($&)operator(.)ident(capitalize) operator(})
+
+
+comment(# @@PLEAC@@_1.10)
+string<delimiter(")content(I have )inline<delimiter(#{)ident(n)operator(+)integer(1)delimiter(})>content( guanacos.)delimiter(")>
+ident(print) string<delimiter(")content(I have )delimiter(")>operator(,) ident(n)operator(+)integer(1)operator(,) string<delimiter(")content( guanacos.)delimiter(")>
+
+
+comment(# @@PLEAC@@_1.11)
+ident(var) operator(=) string<delimiter(<<'EOF')>operator(.)ident(gsub)operator(()regexp<delimiter(/)content(^)char(\\s)content(+)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))string<content(
+ your text
+ goes here)delimiter(
+EOF)>
+
+
+comment(# @@PLEAC@@_1.12)
+ident(string) operator(=) string<delimiter(")content(Folding and splicing is the work of an editor,)char(\\n)delimiter(")>operator(+)
+ string<delimiter(")content(not a mere collection of silicon)char(\\n)delimiter(")>operator(+)
+ string<delimiter(")content(and)char(\\n)delimiter(")>operator(+)
+ string<delimiter(")content(mobile electrons!)delimiter(")>
+
+reserved(def) method(wrap)operator(()ident(str)operator(,) ident(max_size)operator(\))
+ ident(all) operator(=) operator([)operator(])
+ ident(line) operator(=) string<delimiter(')delimiter(')>
+ reserved(for) ident(l) reserved(in) ident(str)operator(.)ident(split)
+ reserved(if) operator(()ident(line)operator(+)ident(l)operator(\))operator(.)ident(length) operator(>)operator(=) ident(max_size)
+ ident(all)operator(.)ident(push)operator(()ident(line)operator(\))
+ ident(line) operator(=) string<delimiter(')delimiter(')>
+ reserved(end)
+ ident(line) operator(+)operator(=) ident(line) operator(==) string<delimiter(')delimiter(')> operator(?) ident(l) operator(:) string<delimiter(')content( )delimiter(')> operator(+) ident(l)
+ reserved(end)
+ ident(all)operator(.)ident(push)operator(()ident(line)operator(\))operator(.)ident(join)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\))
+reserved(end)
+
+ident(print) ident(wrap)operator(()ident(string)operator(,) integer(20)operator(\))
+comment(#=> Folding and )
+comment(#=> splicing is the )
+comment(#=> work of an editor, )
+comment(#=> not a mere )
+comment(#=> collection of )
+comment(#=> silicon and mobile )
+comment(#=> electrons!)
+
+
+comment(# @@PLEAC@@_1.13)
+ident(string) operator(=) string<delimiter(%q()content(Mom said, "Don't do that.")delimiter(\))>
+ident(string)operator(.)ident(gsub)operator(()regexp<delimiter(/)content(['"])delimiter(/)>operator(\)) operator({) string<delimiter(')char(\\\\)delimiter(')>operator(+)global_variable($&) operator(})
+ident(string)operator(.)ident(gsub)operator(()regexp<delimiter(/)content(['"])delimiter(/)>operator(,) string<delimiter(')content(\\&)content(\\&)delimiter(')>operator(\))
+ident(string)operator(.)ident(gsub)operator(()regexp<delimiter(/)content([^A-Z])delimiter(/)>operator(\)) operator({) string<delimiter(')char(\\\\)delimiter(')>operator(+)global_variable($&) operator(})
+string<delimiter(")content(is a test!)delimiter(")>operator(.)ident(gsub)operator(()regexp<delimiter(/)char(\\W)delimiter(/)>operator(\)) operator({) string<delimiter(')char(\\\\)delimiter(')>operator(+)global_variable($&) operator(}) comment(# no function like quotemeta?)
+
+
+comment(# @@PLEAC@@_1.14)
+ident(string)operator(.)ident(strip!)
+
+
+comment(# @@PLEAC@@_1.15)
+reserved(def) method(parse_csv)operator(()ident(text)operator(\))
+ ident(new) operator(=) ident(text)operator(.)ident(scan)operator(()regexp<delimiter(/)content("([^)char(\\")char(\\\\)content(]*(?:)char(\\\\)content(.[^)char(\\")char(\\\\)content(]*\)*\)",?|([^,]+\),?|,)delimiter(/)>operator(\))
+ ident(new) operator(<<) pre_constant(nil) reserved(if) ident(text)operator([)operator(-)integer(1)operator(]) operator(==) integer(?,)
+ ident(new)operator(.)ident(flatten)operator(.)ident(compact)
+reserved(end)
+
+ident(line) operator(=) string<delimiter(%q<)content(XYZZY,"","O'Reilly, Inc","Wall, Larry","a )content(\\")content(glug)content(\\")content( bit,",5,"Error, Core Dumped")delimiter(>)>
+ident(fields) operator(=) ident(parse_csv)operator(()ident(line)operator(\))
+ident(fields)operator(.)ident(each_with_index) operator({) operator(|)ident(v)operator(,)ident(i)operator(|)
+ ident(print) string<delimiter(")inline<delimiter(#{)ident(i)delimiter(})>content( : )inline<delimiter(#{)ident(v)delimiter(})>char(\\n)delimiter(")>operator(;)
+operator(})
+
+
+comment(# @@PLEAC@@_1.16)
+comment(# Use the soundex.rb Library from Michael Neumann.)
+comment(# http://www.s-direktnet.de/homepages/neumann/rb_prgs/Soundex.rb)
+ident(require) string<delimiter(')content(Soundex)delimiter(')>
+
+ident(code) operator(=) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(string)operator(\))
+ident(codes) operator(=) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(array)operator(\))
+
+comment(# substitution function for getpwent(\):)
+comment(# returns an array of user entries,)
+comment(# each entry contains the username and the full name)
+reserved(def) method(login_names)
+ ident(result) operator(=) operator([)operator(])
+ constant(File)operator(.)ident(open)operator(()string<delimiter(")content(/etc/passwd)delimiter(")>operator(\)) operator({) operator(|)ident(file)operator(|)
+ ident(file)operator(.)ident(each_line) operator({) operator(|)ident(line)operator(|)
+ reserved(next) reserved(if) ident(line)operator(.)ident(match)operator(()regexp<delimiter(/)content(^#)delimiter(/)>operator(\))
+ ident(cols) operator(=) ident(line)operator(.)ident(split)operator(()string<delimiter(")content(:)delimiter(")>operator(\))
+ ident(result)operator(.)ident(push)operator(()operator([)ident(cols)operator([)integer(0)operator(])operator(,) ident(cols)operator([)integer(4)operator(])operator(])operator(\))
+ operator(})
+ operator(})
+ ident(result)
+reserved(end)
+
+ident(puts) string<delimiter(")content(Lookup user: )delimiter(")>
+ident(user) operator(=) constant(STDIN)operator(.)ident(gets)
+ident(user)operator(.)ident(chomp!)
+ident(exit) reserved(unless) ident(user)
+ident(name_code) operator(=) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(user)operator(\))
+
+ident(splitter) operator(=) constant(Regexp)operator(.)ident(new)operator(()string<delimiter(')content(()content(\\w)content(+\)[^,]*)content(\\b)content(()content(\\w)content(+\))delimiter(')>operator(\))
+reserved(for) ident(username)operator(,) ident(fullname) reserved(in) ident(login_names) reserved(do)
+ ident(firstname)operator(,) ident(lastname) operator(=) ident(splitter)operator(.)ident(match)operator(()ident(fullname)operator(\))operator([)integer(1)operator(,)integer(2)operator(])
+ reserved(if) ident(name_code) operator(==) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(username)operator(\))
+ operator(||) ident(name_code) operator(==) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(firstname)operator(\))
+ operator(||) ident(name_code) operator(==) constant(Text)operator(::)constant(Soundex)operator(.)ident(soundex)operator(()ident(lastname)operator(\))
+ reserved(then)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(username)delimiter(})>content(: )inline<delimiter(#{)ident(firstname)delimiter(})>content( )inline<delimiter(#{)ident(lastname)delimiter(})>delimiter(")>
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_1.17)
+comment(# @@INCLUDE@@ include/ruby/fixstyle.rb)
+
+
+comment(# @@PLEAC@@_1.18)
+comment(# @@INCLUDE@@ include/ruby/psgrep.rb)
+
+
+comment(# @@PLEAC@@_2.1)
+comment(# Matz tells that you can use Integer(\) for strict checked conversion.)
+constant(Integer)operator(()string<delimiter(")content(abc)delimiter(")>operator(\))
+comment(#=> `Integer': invalid value for Integer: "abc" (ArgumentError\))
+constant(Integer)operator(()string<delimiter(")content(567)delimiter(")>operator(\))
+comment(#=> 567)
+
+comment(# You may use Float(\) for floating point stuff)
+constant(Integer)operator(()string<delimiter(")content(56.7)delimiter(")>operator(\))
+comment(#=> `Integer': invalid value for Integer: "56.7" (ArgumentError\))
+constant(Float)operator(()string<delimiter(")content(56.7)delimiter(")>operator(\))
+comment(#=> 56.7)
+
+comment(# You may also use a regexp for that)
+reserved(if) ident(string) operator(=)operator(~) regexp<delimiter(/)content(^[+-]?)char(\\d)content(+$)delimiter(/)>
+ ident(p) string<delimiter(')content(is an integer)delimiter(')>
+reserved(else)
+ ident(p) string<delimiter(')content(is not)delimiter(')>
+reserved(end)
+
+reserved(if) ident(string) operator(=)operator(~) regexp<delimiter(/)content(^-?(?:)char(\\d)content(+(?:)char(\\.)char(\\d)content(*\)?|)char(\\.)char(\\d)content(+\)$)delimiter(/)>
+ ident(p) string<delimiter(')content(is a decimal number)delimiter(')>
+reserved(else)
+ ident(p) string<delimiter(')content(is not)delimiter(')>
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.2)
+comment(# equal(num1, num2, accuracy\) : returns true if num1 and num2 are)
+comment(# equal to accuracy number of decimal places)
+reserved(def) method(equal)operator(()ident(i)operator(,) ident(j)operator(,) ident(a)operator(\))
+ ident(sprintf)operator(()string<delimiter(")content(%.)inline<delimiter(#{)ident(a)delimiter(})>content(g)delimiter(")>operator(,) ident(i)operator(\)) operator(==) ident(sprintf)operator(()string<delimiter(")content(%.)inline<delimiter(#{)ident(a)delimiter(})>content(g)delimiter(")>operator(,) ident(j)operator(\))
+reserved(end)
+
+ident(wage) operator(=) integer(536) comment(# $5.36/hour)
+ident(week) operator(=) integer(40) operator(*) ident(wage) comment(# $214.40)
+ident(printf)operator(()string<delimiter(")content(One week's wage is: )char(\\$)content(%.2f)char(\\n)delimiter(")>operator(,) ident(week)operator(/)float(100.0)operator(\))
+
+
+comment(# @@PLEAC@@_2.3)
+ident(num)operator(.)ident(round) comment(# rounds to integer)
+
+ident(a) operator(=) float(0.255)
+ident(b) operator(=) ident(sprintf)operator(()string<delimiter(")content(%.2f)delimiter(")>operator(,) ident(a)operator(\))
+ident(print) string<delimiter(")content(Unrounded: )inline<delimiter(#{)ident(a)delimiter(})>char(\\n)content(Rounded: )inline<delimiter(#{)ident(b)delimiter(})>char(\\n)delimiter(")>
+ident(printf) string<delimiter(")content(Unrounded: )inline<delimiter(#{)ident(a)delimiter(})>char(\\n)content(Rounded: %.2f)char(\\n)delimiter(")>operator(,) ident(a)
+
+ident(print) string<delimiter(")content(number)char(\\t)content(int)char(\\t)content(floor)char(\\t)content(ceil)char(\\n)delimiter(")>
+ident(a) operator(=) operator([) float(3.3) operator(,) float(3.5) operator(,) float(3.7)operator(,) operator(-)float(3.3) operator(])
+reserved(for) ident(n) reserved(in) ident(a)
+ ident(printf)operator(()string<delimiter(")content(% .1f)char(\\t)content(% .1f)char(\\t)content(% .1f)char(\\t)content(% .1f)char(\\n)delimiter(")>operator(,) comment(# at least I don't fake my output :\))
+ ident(n)operator(,) ident(n)operator(.)ident(to_i)operator(,) ident(n)operator(.)ident(floor)operator(,) ident(n)operator(.)ident(ceil)operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.4)
+reserved(def) method(dec2bin)operator(()ident(n)operator(\))
+ operator([)ident(n)operator(])operator(.)ident(pack)operator(()string<delimiter(")content(N)delimiter(")>operator(\))operator(.)ident(unpack)operator(()string<delimiter(")content(B32)delimiter(")>operator(\))operator([)integer(0)operator(])operator(.)ident(sub)operator(()regexp<delimiter(/)content(^0+(?=)char(\\d)content(\))delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))
+reserved(end)
+
+reserved(def) method(bin2dec)operator(()ident(n)operator(\))
+ operator([)operator(()string<delimiter(")content(0)delimiter(")>operator(*)integer(32)operator(+)ident(n)operator(.)ident(to_s)operator(\))operator([)operator(-)integer(32)operator(..)operator(-)integer(1)operator(])operator(])operator(.)ident(pack)operator(()string<delimiter(")content(B32)delimiter(")>operator(\))operator(.)ident(unpack)operator(()string<delimiter(")content(N)delimiter(")>operator(\))operator([)integer(0)operator(])
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.5)
+reserved(for) ident(i) reserved(in) ident(x) operator(..) ident(y)
+ comment(# i is set to every integer from x to y, inclusive)
+reserved(end)
+
+ident(x)operator(.)ident(step)operator(()ident(y)operator(,)integer(7)operator(\)) operator({) operator(|)ident(i)operator(|)
+ comment(# i is set to every integer from x to y, stepsize = 7)
+operator(})
+
+ident(print) string<delimiter(")content(Infancy is: )delimiter(")>
+operator(()integer(0)operator(..)integer(2)operator(\))operator(.)ident(each) operator({) operator(|)ident(i)operator(|)
+ ident(print) ident(i)operator(,) string<delimiter(")content( )delimiter(")>
+operator(})
+ident(print) string<delimiter(")char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_2.6)
+comment(# We can add conversion methods to the Integer class,)
+comment(# this makes a roman number just a representation for normal numbers.)
+reserved(class) class(Integer)
+
+ class_variable(@@romanlist) operator(=) operator([)operator([)string<delimiter(")content(M)delimiter(")>operator(,) integer(1000)operator(])operator(,)
+ operator([)string<delimiter(")content(CM)delimiter(")>operator(,) integer(900)operator(])operator(,)
+ operator([)string<delimiter(")content(D)delimiter(")>operator(,) integer(500)operator(])operator(,)
+ operator([)string<delimiter(")content(CD)delimiter(")>operator(,) integer(400)operator(])operator(,)
+ operator([)string<delimiter(")content(C)delimiter(")>operator(,) integer(100)operator(])operator(,)
+ operator([)string<delimiter(")content(XC)delimiter(")>operator(,) integer(90)operator(])operator(,)
+ operator([)string<delimiter(")content(L)delimiter(")>operator(,) integer(50)operator(])operator(,)
+ operator([)string<delimiter(")content(XL)delimiter(")>operator(,) integer(40)operator(])operator(,)
+ operator([)string<delimiter(")content(X)delimiter(")>operator(,) integer(10)operator(])operator(,)
+ operator([)string<delimiter(")content(IX)delimiter(")>operator(,) integer(9)operator(])operator(,)
+ operator([)string<delimiter(")content(V)delimiter(")>operator(,) integer(5)operator(])operator(,)
+ operator([)string<delimiter(")content(IV)delimiter(")>operator(,) integer(4)operator(])operator(,)
+ operator([)string<delimiter(")content(I)delimiter(")>operator(,) integer(1)operator(])operator(])
+
+ reserved(def) method(to_roman)
+ ident(remains) operator(=) pre_constant(self)
+ ident(roman) operator(=) string<delimiter(")delimiter(")>
+ reserved(for) ident(sym)operator(,) ident(num) reserved(in) class_variable(@@romanlist)
+ reserved(while) ident(remains) operator(>)operator(=) ident(num)
+ ident(remains) operator(-)operator(=) ident(num)
+ ident(roman) operator(<<) ident(sym)
+ reserved(end)
+ reserved(end)
+ ident(roman)
+ reserved(end)
+
+ reserved(def) constant(Integer)operator(.)ident(from_roman)operator(()ident(roman)operator(\))
+ ident(ustr) operator(=) ident(roman)operator(.)ident(upcase)
+ ident(sum) operator(=) integer(0)
+ reserved(for) ident(entry) reserved(in) class_variable(@@romanlist)
+ ident(sym)operator(,) ident(num) operator(=) ident(entry)operator([)integer(0)operator(])operator(,) ident(entry)operator([)integer(1)operator(])
+ reserved(while) ident(sym) operator(==) ident(ustr)operator([)integer(0)operator(,) ident(sym)operator(.)ident(length)operator(])
+ ident(sum) operator(+)operator(=) ident(num)
+ ident(ustr)operator(.)ident(slice!)operator(()integer(0)operator(,) ident(sym)operator(.)ident(length)operator(\))
+ reserved(end)
+ reserved(end)
+ ident(sum)
+ reserved(end)
+
+reserved(end)
+
+
+ident(roman_fifteen) operator(=) integer(15)operator(.)ident(to_roman)
+ident(puts) string<delimiter(")content(Roman for fifteen is )inline<delimiter(#{)ident(roman_fifteen)delimiter(})>delimiter(")>
+ident(i) operator(=) constant(Integer)operator(.)ident(from_roman)operator(()ident(roman_fifteen)operator(\))
+ident(puts) string<delimiter(")content(Converted back, )inline<delimiter(#{)ident(roman_fifteen)delimiter(})>content( is )inline<delimiter(#{)ident(i)delimiter(})>delimiter(")>
+
+comment(# check)
+reserved(for) ident(i) reserved(in) operator(()integer(1)operator(..)integer(3900)operator(\))
+ ident(r) operator(=) ident(i)operator(.)ident(to_roman)
+ ident(j) operator(=) constant(Integer)operator(.)ident(from_roman)operator(()ident(r)operator(\))
+ reserved(if) ident(i) operator(!)operator(=) ident(j)
+ ident(puts) string<delimiter(")content(error: )inline<delimiter(#{)ident(i)delimiter(})>content( : )inline<delimiter(#{)ident(r)delimiter(})>content( - )inline<delimiter(#{)ident(j)delimiter(})>delimiter(")>
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.7)
+ident(random) operator(=) ident(rand)operator(()ident(y)operator(-)ident(x)operator(+)integer(1)operator(\))operator(+)ident(x)
+
+ident(chars) operator(=) operator([)string<delimiter(")content(A)delimiter(")>operator(..)string<delimiter(")content(Z)delimiter(")>operator(,)string<delimiter(")content(a)delimiter(")>operator(..)string<delimiter(")content(z)delimiter(")>operator(,)string<delimiter(")content(0)delimiter(")>operator(..)string<delimiter(")content(9)delimiter(")>operator(])operator(.)ident(collect) operator({) operator(|)ident(r)operator(|) ident(r)operator(.)ident(to_a) operator(})operator(.)ident(join) operator(+) string<delimiter(%q()content(!@$%^&*)delimiter(\))>
+ident(password) operator(=) operator(()integer(1)operator(..)integer(8)operator(\))operator(.)ident(collect) operator({) ident(chars)operator([)ident(rand)operator(()ident(chars)operator(.)ident(size)operator(\))operator(]) operator(})operator(.)ident(pack)operator(()string<delimiter(")content(C*)delimiter(")>operator(\))
+
+
+comment(# @@PLEAC@@_2.8)
+ident(srand) comment(# uses a combination of the time, the process id, and a sequence number)
+ident(srand)operator(()ident(val)operator(\)) comment(# for repeatable behaviour)
+
+
+comment(# @@PLEAC@@_2.9)
+comment(# from the randomr lib: )
+comment(# http://raa.ruby-lang.org/project/randomr/)
+operator(-)operator(-)operator(-)operator(-)operator(>) ident(http)symbol(:/)operator(/)ident(raa)operator(.)ident(ruby)operator(-)ident(lang)operator(.)ident(org)operator(/)ident(project)operator(/)ident(randomr)operator(/)
+
+ident(require) string<delimiter(')content(random/mersenne_twister)delimiter(')>
+ident(mers) operator(=) constant(Random)operator(::)constant(MersenneTwister)operator(.)ident(new) integer(123456789)
+ident(puts) ident(mers)operator(.)ident(rand)operator(()integer(0)operator(\)) comment(# 0.550321932544541)
+ident(puts) ident(mers)operator(.)ident(rand)operator(()integer(10)operator(\)) comment(# 2)
+
+comment(# using online sources of random data via the realrand package:)
+comment(# http://raa.ruby-lang.org/project/realrand/)
+comment(# **Note**)
+comment(# The following online services are used in this package:)
+comment(# http://www.random.org - source: atmospheric noise )
+comment(# http://www.fourmilab.ch/hotbits - source: radioactive decay timings)
+comment(# http://random.hd.org - source: entropy from local and network noise)
+comment(# Please visit the sites and respect the rules of each service.)
+
+ident(require) string<delimiter(')content(random/online)delimiter(')>
+
+ident(generator1) operator(=) constant(Random)operator(::)constant(RandomOrg)operator(.)ident(new)
+ident(puts) ident(generator1)operator(.)ident(randbyte)operator(()integer(5)operator(\))operator(.)ident(join)operator(()string<delimiter(")content(,)delimiter(")>operator(\))
+ident(puts) ident(generator1)operator(.)ident(randnum)operator(()integer(10)operator(,) integer(1)operator(,) integer(6)operator(\))operator(.)ident(join)operator(()string<delimiter(")content(,)delimiter(")>operator(\)) comment(# Roll dice 10 times.)
+
+ident(generator2) operator(=) constant(Random)operator(::)constant(FourmiLab)operator(.)ident(new)
+ident(puts) ident(generator2)operator(.)ident(randbyte)operator(()integer(5)operator(\))operator(.)ident(join)operator(()string<delimiter(")content(,)delimiter(")>operator(\))
+comment(# randnum is not supported.)
+
+ident(generator3) operator(=) constant(Random)operator(::)constant(EntropyPool)operator(.)ident(new)
+ident(puts) ident(generator3)operator(.)ident(randbyte)operator(()integer(5)operator(\))operator(.)ident(join)operator(()string<delimiter(")content(,)delimiter(")>operator(\))
+comment(# randnum is not supported.)
+
+
+comment(# @@PLEAC@@_2.10)
+reserved(def) method(gaussian_rand)
+ reserved(begin)
+ ident(u1) operator(=) integer(2) operator(*) ident(rand)operator(()operator(\)) operator(-) integer(1)
+ ident(u2) operator(=) integer(2) operator(*) ident(rand)operator(()operator(\)) operator(-) integer(1)
+ ident(w) operator(=) ident(u1)operator(*)ident(u1) operator(+) ident(u2)operator(*)ident(u2)
+ reserved(end) reserved(while) operator(()ident(w) operator(>)operator(=) integer(1)operator(\))
+ ident(w) operator(=) constant(Math)operator(.)ident(sqrt)operator(()operator(()operator(-)integer(2)operator(*)constant(Math)operator(.)ident(log)operator(()ident(w)operator(\))operator(\))operator(/)ident(w)operator(\))
+ operator([) ident(u2)operator(*)ident(w)operator(,) ident(u1)operator(*)ident(w) operator(])
+reserved(end)
+
+ident(mean) operator(=) integer(25)
+ident(sdev) operator(=) integer(2)
+ident(salary) operator(=) ident(gaussian_rand)operator([)integer(0)operator(]) operator(*) ident(sdev) operator(+) ident(mean)
+ident(printf)operator(()string<delimiter(")content(You have been hired at )char(\\$)content(%.2f)char(\\n)delimiter(")>operator(,) ident(salary)operator(\))
+
+
+comment(# @@PLEAC@@_2.11)
+reserved(def) method(deg2rad)operator(()ident(d)operator(\))
+ operator(()ident(d)operator(/)float(180.0)operator(\))operator(*)constant(Math)operator(::)constant(PI)
+reserved(end)
+
+reserved(def) method(rad2deg)operator(()ident(r)operator(\))
+ operator(()ident(r)operator(/)constant(Math)operator(::)constant(PI)operator(\))operator(*)integer(180)
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.12)
+ident(sin_val) operator(=) constant(Math)operator(.)ident(sin)operator(()ident(angle)operator(\))
+ident(cos_val) operator(=) constant(Math)operator(.)ident(cos)operator(()ident(angle)operator(\))
+ident(tan_val) operator(=) constant(Math)operator(.)ident(tan)operator(()ident(angle)operator(\))
+
+comment(# AFAIK Ruby's Math module doesn't provide acos/asin)
+comment(# While we're at it, let's also define missing hyperbolic functions)
+reserved(module) class(Math)
+ reserved(def) constant(Math)operator(.)ident(asin)operator(()ident(x)operator(\))
+ ident(atan2)operator(()ident(x)operator(,) ident(sqrt)operator(()integer(1) operator(-) ident(x)operator(**)integer(2)operator(\))operator(\))
+ reserved(end)
+ reserved(def) constant(Math)operator(.)ident(acos)operator(()ident(x)operator(\))
+ ident(atan2)operator(()ident(sqrt)operator(()integer(1) operator(-) ident(x)operator(**)integer(2)operator(\))operator(,) ident(x)operator(\))
+ reserved(end)
+ reserved(def) constant(Math)operator(.)ident(atan)operator(()ident(x)operator(\))
+ ident(atan2)operator(()ident(x)operator(,) integer(1)operator(\))
+ reserved(end)
+ reserved(def) constant(Math)operator(.)ident(sinh)operator(()ident(x)operator(\))
+ operator(()ident(exp)operator(()ident(x)operator(\)) operator(-) ident(exp)operator(()operator(-)ident(x)operator(\))operator(\)) operator(/) integer(2)
+ reserved(end)
+ reserved(def) constant(Math)operator(.)ident(cosh)operator(()ident(x)operator(\))
+ operator(()ident(exp)operator(()ident(x)operator(\)) operator(+) ident(exp)operator(()operator(-)ident(x)operator(\))operator(\)) operator(/) integer(2)
+ reserved(end)
+ reserved(def) constant(Math)operator(.)ident(tanh)operator(()ident(x)operator(\))
+ ident(sinh)operator(()ident(x)operator(\)) operator(/) ident(cosh)operator(()ident(x)operator(\))
+ reserved(end)
+reserved(end)
+
+comment(# The support for Complex numbers is not built-in)
+ident(y) operator(=) constant(Math)operator(.)ident(acos)operator(()float(3.7)operator(\))
+comment(#=> in `sqrt': square root for negative number (ArgumentError\))
+
+comment(# There is an implementation of Complex numbers in 'complex.rb' in current)
+comment(# Ruby distro, but it doesn't support atan2 with complex args, so it doesn't)
+comment(# solve this problem.)
+
+
+comment(# @@PLEAC@@_2.13)
+ident(log_e) operator(=) constant(Math)operator(.)ident(log)operator(()ident(val)operator(\))
+ident(log_10) operator(=) constant(Math)operator(.)ident(log10)operator(()ident(val)operator(\))
+
+reserved(def) method(log_base)operator(()ident(base)operator(,) ident(val)operator(\))
+ constant(Math)operator(.)ident(log)operator(()ident(val)operator(\))operator(/)constant(Math)operator(.)ident(log)operator(()ident(base)operator(\))
+reserved(end)
+
+ident(answer) operator(=) ident(log_base)operator(()integer(10)operator(,) integer(10_000)operator(\))
+ident(puts) string<delimiter(")content(log10(10,000\) = )inline<delimiter(#{)ident(answer)delimiter(})>delimiter(")>
+
+
+comment(# @@PLEAC@@_2.14)
+ident(require) string<delimiter(')content(matrix.rb)delimiter(')>
+
+ident(a) operator(=) constant(Matrix)operator([)operator([)integer(3)operator(,) integer(2)operator(,) integer(3)operator(])operator(,) operator([)integer(5)operator(,) integer(9)operator(,) integer(8)operator(])operator(])
+ident(b) operator(=) constant(Matrix)operator([)operator([)integer(4)operator(,) integer(7)operator(])operator(,) operator([)integer(9)operator(,) integer(3)operator(])operator(,) operator([)integer(8)operator(,) integer(1)operator(])operator(])
+ident(c) operator(=) ident(a) operator(*) ident(b)
+
+ident(a)operator(.)ident(row_size)
+ident(a)operator(.)ident(column_size)
+
+ident(c)operator(.)ident(det)
+ident(a)operator(.)ident(transpose)
+
+
+comment(# @@PLEAC@@_2.15)
+ident(require) string<delimiter(')content(complex.rb)delimiter(')>
+ident(require) string<delimiter(')content(rational.rb)delimiter(')>
+
+ident(a) operator(=) constant(Complex)operator(()integer(3)operator(,) integer(5)operator(\)) comment(# 3 + 5i)
+ident(b) operator(=) constant(Complex)operator(()integer(2)operator(,) operator(-)integer(2)operator(\)) comment(# 2 - 2i)
+ident(puts) string<delimiter(")content(c = )inline<delimiter(#{)ident(a)operator(*)ident(b)delimiter(})>delimiter(")>
+
+ident(c) operator(=) ident(a) operator(*) ident(b)
+ident(d) operator(=) integer(3) operator(+) integer(4)operator(*)constant(Complex)operator(::)constant(I)
+
+ident(printf) string<delimiter(")content(sqrt()inline<delimiter(#{)ident(d)delimiter(})>content(\) = %s)char(\\n)delimiter(")>operator(,) constant(Math)operator(.)ident(sqrt)operator(()ident(d)operator(\))
+
+
+comment(# @@PLEAC@@_2.16)
+ident(number) operator(=) ident(hexadecimal)operator(.)ident(hex)
+ident(number) operator(=) ident(octal)operator(.)ident(oct)
+
+ident(print) string<delimiter(")content(Gimme a number in decimal, octal, or hex: )delimiter(")>
+ident(num) operator(=) ident(gets)operator(.)ident(chomp)
+ident(exit) reserved(unless) reserved(defined?)operator(()ident(num)operator(\))
+ident(num) operator(=) ident(num)operator(.)ident(oct) reserved(if) ident(num) operator(=)operator(~) regexp<delimiter(/)content(^0)delimiter(/)> comment(# does both oct and hex )
+ident(printf) string<delimiter(")content(%d %x %o)char(\\n)delimiter(")>operator(,) ident(num)operator(,) ident(num)operator(,) ident(num)
+
+ident(print) string<delimiter(")content(Enter file permission in octal: )delimiter(")>
+ident(permissions) operator(=) ident(gets)operator(.)ident(chomp)
+ident(raise) string<delimiter(")content(Exiting ...)char(\\n)delimiter(")> reserved(unless) reserved(defined?)operator(()ident(permissions)operator(\))
+ident(puts) string<delimiter(")content(The decimal value is )inline<delimiter(#{)ident(permissions)operator(.)ident(oct)delimiter(})>delimiter(")>
+
+
+comment(# @@PLEAC@@_2.17)
+reserved(def) method(commify)operator(()ident(n)operator(\))
+ ident(n)operator(.)ident(to_s) operator(=)operator(~) regexp<delimiter(/)content(([^)char(\\.)content(]*\)()char(\\.)content(.*\)?)delimiter(/)>
+ ident(int)operator(,) ident(dec) operator(=) global_variable($1)operator(.)ident(reverse)operator(,) global_variable($2) operator(?) global_variable($2) operator(:) string<delimiter(")delimiter(")>
+ reserved(while) ident(int)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content((,|)char(\\.)content(|^\)()char(\\d)content({3}\)()char(\\d)content(\))delimiter(/)>operator(,) string<delimiter(')content(\\1)content(\\2)content(,)content(\\3)delimiter(')>operator(\))
+ reserved(end)
+ ident(int)operator(.)ident(reverse) operator(+) ident(dec)
+reserved(end)
+
+
+comment(# @@PLEAC@@_2.18)
+ident(printf) string<delimiter(")content(It took %d hour%s)char(\\n)delimiter(")>operator(,) ident(time)operator(,) ident(time) operator(==) integer(1) operator(?) string<delimiter(")delimiter(")> operator(:) string<delimiter(")content(s)delimiter(")>
+
+comment(# dunno if an equivalent to Lingua::EN::Inflect exists...)
+
+
+comment(# @@PLEAC@@_2.19)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby)
+comment(# bigfact - calculating prime factors)
+reserved(def) method(factorize)operator(()ident(orig)operator(\))
+ ident(factors) operator(=) operator({)operator(})
+ ident(factors)operator(.)ident(default) operator(=) integer(0) comment(# return 0 instead nil if key not found in hash)
+ ident(n) operator(=) ident(orig)
+ ident(i) operator(=) integer(2)
+ ident(sqi) operator(=) integer(4) comment(# square of i)
+ reserved(while) ident(sqi) operator(<=) ident(n) reserved(do)
+ reserved(while) ident(n)operator(.)ident(modulo)operator(()ident(i)operator(\)) operator(==) integer(0) reserved(do)
+ ident(n) regexp<delimiter(/)content(= i
+ factors[i] += 1
+ # puts "Found factor )inline<delimiter(#{)ident(i)delimiter(})>content("
+ end
+ # we take advantage of the fact that (i +1\)**2 = i**2 + 2*i +1
+ sqi += 2 * i + 1
+ i += 1
+ end
+
+ if (n != 1\) && (n != orig\)
+ factors[n] += 1
+ end
+ factors
+end
+
+def printfactorhash(orig, factorcount\)
+ print format("%-10d ", orig\)
+ if factorcount.length == 0
+ print "PRIME"
+ else
+ # sorts after number, because the hash keys are numbers
+ factorcount.sort.each { |factor,exponent|
+ print factor
+ if exponent > 1
+ print "**", exponent
+ end
+ print " "
+ }
+ end
+ puts
+end
+
+for arg in ARGV
+ n = arg.to_i
+ mfactors = factorize(n\)
+ printfactorhash(n, mfactors\)
+end
+#-----------------------------
+
+
+# @@PLEAC@@_3.0
+puts Time.now
+
+print "Today is day ", Time.now.yday, " of the current year.)char(\\n)content("
+print "Today is day ", Time.now.day, " of the current month.)char(\\n)content("
+
+
+# @@PLEAC@@_3.1
+day, month, year = Time.now.day, Time.now.month, Time.now.year
+# or
+day, month, year = Time.now.to_a[3..5]
+
+tl = Time.now.localtime
+printf("The current date is %04d %02d %02d)char(\\n)content(", tl.year, tl.month, tl.day\)
+
+Time.now.localtime.strftime("%Y-%m-%d"\)
+
+
+# @@PLEAC@@_3.2
+Time.local(year, month, day, hour, minute, second\).tv_sec
+Time.gm(year, month, day, hour, minute, second\).tv_sec
+
+
+# @@PLEAC@@_3.3
+sec, min, hour, day, month, year, wday, yday, isdst, zone = Time.at(epoch_secs\).to_a
+
+
+# @@PLEAC@@_3.4
+when_ = now + difference # now -> Time ; difference -> Numeric (delta in seconds\)
+then_ = now - difference
+
+
+# @@PLEAC@@_3.5
+bree = 361535725
+nat = 96201950
+
+difference = bree - nat
+puts "There were )inline<delimiter(#{)ident(difference)delimiter(})>content( seconds between Nat and Bree"
+
+seconds = difference % 60
+difference = (difference - seconds\) )delimiter(/)> integer(60)
+ident(minutes) operator(=) ident(difference) operator(%) integer(60)
+ident(difference) operator(=) operator(()ident(difference) operator(-) ident(minutes)operator(\)) operator(/) integer(60)
+ident(hours) operator(=) ident(difference) operator(%) integer(24)
+ident(difference) operator(=) operator(()ident(difference) operator(-) ident(hours)operator(\)) operator(/) integer(24)
+ident(days) operator(=) ident(difference) operator(%) integer(7)
+ident(weeks) operator(=) operator(()ident(difference) operator(-) ident(days)operator(\)) operator(/) integer(7)
+
+ident(puts) string<delimiter(")content(()inline<delimiter(#{)ident(weeks)delimiter(})>content( weeks, )inline<delimiter(#{)ident(days)delimiter(})>content( days, )inline<delimiter(#{)ident(hours)delimiter(})>content(:)inline<delimiter(#{)ident(minutes)delimiter(})>content(:)inline<delimiter(#{)ident(seconds)delimiter(})>content(\))delimiter(")>
+
+
+comment(# @@PLEAC@@_3.6)
+ident(monthday)operator(,) ident(weekday)operator(,) ident(yearday) operator(=) ident(date)operator(.)ident(mday)operator(,) ident(date)operator(.)ident(wday)operator(,) ident(date)operator(.)ident(yday)
+
+comment(# AFAIK the week number is not just a division since week boundaries are on sundays)
+ident(weeknum) operator(=) ident(d)operator(.)ident(strftime)operator(()string<delimiter(")content(%U)delimiter(")>operator(\))operator(.)ident(to_i) operator(+) integer(1)
+
+ident(year) operator(=) integer(1981)
+ident(month) operator(=) string<delimiter(")content(jun)delimiter(")> comment(# or `6' if you want to emulate a broken language)
+ident(day) operator(=) integer(16)
+ident(t) operator(=) constant(Time)operator(.)ident(mktime)operator(()ident(year)operator(,) ident(month)operator(,) ident(day)operator(\))
+ident(print) string<delimiter(")inline<delimiter(#{)ident(month)delimiter(})>content(/)inline<delimiter(#{)ident(day)delimiter(})>content(/)inline<delimiter(#{)ident(year)delimiter(})>content( was a )delimiter(")>operator(,) ident(t)operator(.)ident(strftime)operator(()string<delimiter(")content(%A)delimiter(")>operator(\))operator(,) string<delimiter(")char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_3.7)
+ident(yyyy)operator(,) ident(mm)operator(,) ident(dd) operator(=) global_variable($1)operator(,) global_variable($2)operator(,) global_variable($3) reserved(if) string<delimiter(")content(1998-06-25)delimiter(")> operator(=)operator(~) regexp<delimiter(/)content(()char(\\d)content(+\)-()char(\\d)content(+\)-()char(\\d)content(+\))delimiter(/)>
+
+ident(epoch_seconds) operator(=) constant(Time)operator(.)ident(mktime)operator(()ident(yyyy)operator(,) ident(mm)operator(,) ident(dd)operator(\))operator(.)ident(tv_sec)
+
+comment(# dunno an equivalent to Date::Manip#ParseDate)
+
+
+comment(# @@PLEAC@@_3.8)
+ident(string) operator(=) constant(Time)operator(.)ident(at)operator(()ident(epoch_secs)operator(\))
+constant(Time)operator(.)ident(at)operator(()integer(1234567890)operator(\))operator(.)ident(gmtime) comment(# gives: Fri Feb 13 23:31:30 UTC 2009)
+
+ident(time) operator(=) constant(Time)operator(.)ident(mktime)operator(()integer(1973)operator(,) string<delimiter(")content(jan)delimiter(")>operator(,) integer(18)operator(,) integer(3)operator(,) integer(45)operator(,) integer(50)operator(\))
+ident(print) string<delimiter(")content(In localtime it gives: )delimiter(")>operator(,) ident(time)operator(.)ident(localtime)operator(,) string<delimiter(")char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_3.9)
+comment(# Ruby provides micro-seconds in Time object)
+constant(Time)operator(.)ident(now)operator(.)ident(usec)
+
+comment(# Ruby gives the seconds in floating format when substracting two Time objects)
+ident(before) operator(=) constant(Time)operator(.)ident(now)
+ident(line) operator(=) ident(gets)
+ident(elapsed) operator(=) constant(Time)operator(.)ident(now) operator(-) ident(before)
+ident(puts) string<delimiter(")content(You took )inline<delimiter(#{)ident(elapsed)delimiter(})>content( seconds.)delimiter(")>
+
+comment(# On my Celeron-400 with Linux-2.2.19-14mdk, average for three execs are:)
+comment(# This Ruby version: average 0.00321 sec)
+comment(# Cookbook's Perl version: average 0.00981 sec)
+ident(size) operator(=) integer(500)
+ident(number_of_times) operator(=) integer(100)
+ident(total_time) operator(=) integer(0)
+ident(number_of_times)operator(.)ident(times) operator({)
+ comment(# populate array)
+ ident(array) operator(=) operator([)operator(])
+ ident(size)operator(.)ident(times) operator({) ident(array) operator(<<) ident(rand) operator(})
+ comment(# sort it)
+ ident(begin_) operator(=) constant(Time)operator(.)ident(now)
+ ident(array)operator(.)ident(sort!)
+ ident(time) operator(=) constant(Time)operator(.)ident(now) operator(-) ident(begin_)
+ ident(total_time) operator(+)operator(=) ident(time)
+operator(})
+ident(printf) string<delimiter(")content(On average, sorting %d random numbers takes %.5f seconds)char(\\n)delimiter(")>operator(,)
+ ident(size)operator(,) operator(()ident(total_time)operator(/)constant(Float)operator(()ident(number_of_times)operator(\))operator(\))
+
+
+comment(# @@PLEAC@@_3.10)
+ident(sleep)operator(()float(0.005)operator(\)) comment(# Ruby is definitely not as broken as Perl :\))
+comment(# (may be interrupted by sending the process a SIGALRM\))
+
+
+comment(# @@PLEAC@@_3.11)
+comment(#!/usr/bin/ruby -w)
+comment(# hopdelta - feed mail header, produce lines)
+comment(# showing delay at each hop.)
+ident(require) string<delimiter(')content(time)delimiter(')>
+reserved(class) class(MailHopDelta)
+
+ reserved(def) method(initialize)operator(()ident(mail)operator(\))
+ instance_variable(@head) operator(=) ident(mail)operator(.)ident(gsub)operator(()regexp<delimiter(/)char(\\n)char(\\s)content(+)delimiter(/)>operator(,)string<delimiter(')content( )delimiter(')>operator(\))
+ instance_variable(@topline) operator(=) string<delimiter(%w-)content(Sender Recipient Time Delta)delimiter(-)>
+ instance_variable(@start_from) operator(=) ident(mail)operator(.)ident(match)operator(()regexp<delimiter(/)content(^From.*)char(\\@)content(([^)char(\\s)content(>]*\))delimiter(/)>operator(\))operator([)integer(1)operator(])
+ instance_variable(@date) operator(=) constant(Time)operator(.)ident(parse)operator(()ident(mail)operator(.)ident(match)operator(()regexp<delimiter(/)content(^Date:)char(\\s)content(+(.*\))delimiter(/)>operator(\))operator([)integer(1)operator(])operator(\))
+ reserved(end)
+
+ reserved(def) method(out)operator(()ident(line)operator(\))
+ string<delimiter(")content(%-20.20s %-20.20s %-20.20s %s)delimiter(")> operator(%) ident(line)
+ reserved(end)
+
+ reserved(def) method(hop_date)operator(()ident(day)operator(\))
+ ident(day)operator(.)ident(strftime)operator(()string<delimiter(")content(%I:%M:%S %Y/%m/%d)delimiter(")>operator(\))
+ reserved(end)
+
+ reserved(def) method(puts_hops)
+ ident(puts) ident(out)operator(()instance_variable(@topline)operator(\))
+ ident(puts) ident(out)operator(()operator([)string<delimiter(')content(Start)delimiter(')>operator(,) instance_variable(@start_from)operator(,) ident(hop_date)operator(()instance_variable(@date)operator(\))operator(,)string<delimiter(')delimiter(')>operator(])operator(\))
+ instance_variable(@head)operator(.)ident(split)operator(()regexp<delimiter(/)char(\\n)delimiter(/)>operator(\))operator(.)ident(reverse)operator(.)ident(grep)operator(()regexp<delimiter(/)content(^Received:)delimiter(/)>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(hop)operator(|)
+ ident(hop)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\b)content(on (.*?\) (id.*\))delimiter(/)>operator(,)string<delimiter(')content(; )content(\\1)delimiter(')>operator(\))
+ ident(whence) operator(=) ident(hop)operator(.)ident(match)operator(()regexp<delimiter(/)content(;)char(\\s)content(+(.*\)$)delimiter(/)>operator(\))operator([)integer(1)operator(])
+ reserved(unless) ident(whence)
+ ident(warn) string<delimiter(")content(Bad received line: )inline<delimiter(#{)ident(hop)delimiter(})>delimiter(")>
+ reserved(next)
+ reserved(end)
+ ident(from) operator(=) global_variable($+) reserved(if) ident(hop) operator(=)operator(~) regexp<delimiter(/)content(from)char(\\s)content(+()char(\\S)content(+\)|)char(\\()content((.*?\))char(\\\))delimiter(/)>
+ ident(by) operator(=) global_variable($1) reserved(if) ident(hop) operator(=)operator(~) regexp<delimiter(/)content(by)char(\\s)content(+()char(\\S)content(+)char(\\.)char(\\S)content(+\))delimiter(/)>
+ reserved(next) reserved(unless) ident(now) operator(=) constant(Time)operator(.)ident(parse)operator(()ident(whence)operator(\))operator(.)ident(localtime)
+ ident(delta) operator(=) ident(now) operator(-) instance_variable(@date)
+ ident(puts) ident(out)operator(()operator([)ident(from)operator(,) ident(by)operator(,) ident(hop_date)operator(()ident(now)operator(\))operator(,) ident(hop_time)operator(()ident(delta)operator(\))operator(])operator(\))
+ instance_variable(@date) operator(=) ident(now)
+ reserved(end)
+ reserved(end)
+
+ reserved(def) method(hop_time)operator(()ident(secs)operator(\))
+ ident(sign) operator(=) ident(secs) operator(<) integer(0) operator(?) operator(-)integer(1) operator(:) integer(1)
+ ident(days)operator(,) ident(secs) operator(=) ident(secs)operator(.)ident(abs)operator(.)ident(divmod)operator(()integer(60) operator(*) integer(60) operator(*) integer(24)operator(\))
+ ident(hours)operator(,)ident(secs) operator(=) ident(secs)operator(.)ident(abs)operator(.)ident(divmod)operator(()integer(60) operator(*) integer(60)operator(\))
+ ident(mins)operator(,) ident(secs) operator(=) ident(secs)operator(.)ident(abs)operator(.)ident(divmod)operator(()integer(60)operator(\))
+ ident(rtn) operator(=) string<delimiter(")content(%3ds)delimiter(")> operator(%) operator([)ident(secs) operator(*) ident(sign)operator(])
+ ident(rtn) operator(<<) string<delimiter(")content(%3dm)delimiter(")> operator(%) operator([)ident(mins) operator(*) ident(sign)operator(]) reserved(if) ident(mins) operator(!)operator(=) integer(0)
+ ident(rtn) operator(<<) string<delimiter(")content(%3dh)delimiter(")> operator(%) operator([)ident(hours) operator(*) ident(sign)operator(]) reserved(if) ident(hours) operator(!)operator(=) integer(0)
+ ident(rtn) operator(<<) string<delimiter(")content(%3dd)delimiter(")> operator(%) operator([)ident(days) operator(*) ident(sign)operator(]) reserved(if) ident(days) operator(!)operator(=) integer(0)
+ ident(rtn)
+ reserved(end)
+reserved(end)
+
+global_variable($/) operator(=) string<delimiter(")delimiter(")>
+ident(mail) operator(=) constant(MailHopDelta)operator(.)ident(new)operator(()pre_constant(ARGF)operator(.)ident(gets)operator(\))operator(.)ident(puts_hops)
+
+
+comment(# @@PLEAC@@_4.0)
+ident(single_level) operator(=) operator([) string<delimiter(")content(this)delimiter(")>operator(,) string<delimiter(")content(that)delimiter(")>operator(,) string<delimiter(")content(the)delimiter(")>operator(,) string<delimiter(")content(other)delimiter(")> operator(])
+
+comment(# Ruby directly supports nested arrays)
+ident(double_level) operator(=) operator([) string<delimiter(")content(this)delimiter(")>operator(,) string<delimiter(")content(that)delimiter(")>operator(,) operator([) string<delimiter(")content(the)delimiter(")>operator(,) string<delimiter(")content(other)delimiter(")> operator(]) operator(])
+ident(still_single_level) operator(=) operator([) string<delimiter(")content(this)delimiter(")>operator(,) string<delimiter(")content(that)delimiter(")>operator(,) operator([) string<delimiter(")content(the)delimiter(")>operator(,) string<delimiter(")content(other)delimiter(")> operator(]) operator(])operator(.)ident(flatten)
+
+
+comment(# @@PLEAC@@_4.1)
+ident(a) operator(=) operator([) string<delimiter(")content(quick)delimiter(")>operator(,) string<delimiter(")content(brown)delimiter(")>operator(,) string<delimiter(")content(fox)delimiter(")> operator(])
+ident(a) operator(=) string<delimiter(%w()content(Why are you teasing me?)delimiter(\))>
+
+ident(lines) operator(=) string<delimiter(<<"END_OF_HERE_DOC")>operator(.)ident(gsub)operator(()regexp<delimiter(/)content(^)char(\\s)content(*(.+\))delimiter(/)>operator(,) string<delimiter(')content(\\1)delimiter(')>operator(\))string<content(
+ The boy stood on the burning deck,
+ It was as hot as glass.)delimiter(
+END_OF_HERE_DOC)>
+
+ident(bigarray) operator(=) constant(IO)operator(.)ident(readlines)operator(()string<delimiter(")content(mydatafile)delimiter(")>operator(\))operator(.)ident(collect) operator({) operator(|)ident(l)operator(|) ident(l)operator(.)ident(chomp) operator(})
+
+ident(name) operator(=) string<delimiter(")content(Gandalf)delimiter(")>
+ident(banner) operator(=) string<delimiter(%Q()content(Speak, )inline<delimiter(#{)ident(name)delimiter(})>content(, and welcome!)delimiter(\))>
+
+ident(host_info) operator(=) shell<delimiter(`)content(host )inline<delimiter(#{)ident(his_host)delimiter(})>delimiter(`)>
+
+shell<delimiter(%x()content(ps )inline<delimiter(#{)global_variable($$)delimiter(})>delimiter(\))>
+
+ident(banner) operator(=) string<delimiter(')content(Costs only $4.95)delimiter(')>operator(.)ident(split)operator(()string<delimiter(')content( )delimiter(')>operator(\))
+
+ident(rax) operator(=) string<delimiter(%w!)content( ( \) < > { } [ ] )delimiter(!)>
+
+
+comment(# @@PLEAC@@_4.2)
+reserved(def) method(commify_series)operator(()ident(arr)operator(\))
+ reserved(return) string<delimiter(')delimiter(')> reserved(if) reserved(not) ident(arr)
+ reserved(case) ident(arr)operator(.)ident(size)
+ reserved(when) integer(0) reserved(then) string<delimiter(')delimiter(')>
+ reserved(when) integer(1) reserved(then) ident(arr)operator([)integer(0)operator(])
+ reserved(when) integer(2) reserved(then) ident(arr)operator(.)ident(join)operator(()string<delimiter(')content( and )delimiter(')>operator(\))
+ reserved(else) ident(arr)operator([)integer(0)operator(..)operator(-)integer(2)operator(])operator(.)ident(join)operator(()string<delimiter(')content(, )delimiter(')>operator(\)) operator(+) string<delimiter(')content(, and )delimiter(')> operator(+) ident(arr)operator([)operator(-)integer(1)operator(])
+ reserved(end)
+reserved(end)
+
+ident(array) operator(=) operator([) string<delimiter(")content(red)delimiter(")>operator(,) string<delimiter(")content(yellow)delimiter(")>operator(,) string<delimiter(")content(green)delimiter(")> operator(])
+
+ident(print) string<delimiter(")content(I have )delimiter(")>operator(,) ident(array)operator(,) string<delimiter(")content( marbles)char(\\n)delimiter(")>
+comment(# -> I have redyellowgreen marbles)
+
+comment(# But unlike Perl:)
+ident(print) string<delimiter(")content(I have )inline<delimiter(#{)ident(array)delimiter(})>content( marbles)char(\\n)delimiter(")>
+comment(# -> I have redyellowgreen marbles)
+comment(# So, needs:)
+ident(print) string<delimiter(")content(I have )inline<delimiter(#{)ident(array)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>content( marbles)char(\\n)delimiter(")>
+comment(# -> I have red yellow green marbles)
+
+comment(#!/usr/bin/ruby)
+comment(# communify_series - show proper comma insertion in list output)
+
+reserved(def) method(commify_series)operator(()ident(arr)operator(\))
+ reserved(return) string<delimiter(')delimiter(')> reserved(if) reserved(not) ident(arr)
+ ident(sepchar) operator(=) ident(arr)operator(.)ident(find) operator({) operator(|)ident(p)operator(|) ident(p) operator(=)operator(~) regexp<delimiter(/)content(,)delimiter(/)> operator(}) operator(?) string<delimiter(')content(; )delimiter(')> operator(:) string<delimiter(')content(, )delimiter(')>
+ reserved(case) ident(arr)operator(.)ident(size)
+ reserved(when) integer(0) reserved(then) string<delimiter(')delimiter(')>
+ reserved(when) integer(1) reserved(then) ident(arr)operator([)integer(0)operator(])
+ reserved(when) integer(2) reserved(then) ident(arr)operator(.)ident(join)operator(()string<delimiter(')content( and )delimiter(')>operator(\))
+ reserved(else) ident(arr)operator([)integer(0)operator(..)operator(-)integer(2)operator(])operator(.)ident(join)operator(()ident(sepchar)operator(\)) operator(+) ident(sepchar) operator(+) string<delimiter(')content(and )delimiter(')> operator(+) ident(arr)operator([)operator(-)integer(1)operator(])
+ reserved(end)
+reserved(end)
+
+ident(lists) operator(=) operator([)
+ operator([) string<delimiter(')content(just one thing)delimiter(')> operator(])operator(,)
+ string<delimiter(%w()content(Mutt Jeff)delimiter(\))>operator(,)
+ string<delimiter(%w()content(Peter Paul Mary)delimiter(\))>operator(,)
+ operator([) string<delimiter(')content(To our parents)delimiter(')>operator(,) string<delimiter(')content(Mother Theresa)delimiter(')>operator(,) string<delimiter(')content(God)delimiter(')> operator(])operator(,)
+ operator([) string<delimiter(')content(pastrami)delimiter(')>operator(,) string<delimiter(')content(ham and cheese)delimiter(')>operator(,) string<delimiter(')content(peanut butter and jelly)delimiter(')>operator(,) string<delimiter(')content(tuna)delimiter(')> operator(])operator(,)
+ operator([) string<delimiter(')content(recycle tired, old phrases)delimiter(')>operator(,) string<delimiter(')content(ponder big, happy thoughts)delimiter(')> operator(])operator(,)
+ operator([) string<delimiter(')content(recycle tired, old phrases)delimiter(')>operator(,)
+ string<delimiter(')content(ponder big, happy thoughts)delimiter(')>operator(,)
+ string<delimiter(')content(sleep and dream peacefully)delimiter(')> operator(])operator(,)
+operator(])
+
+reserved(for) ident(list) reserved(in) ident(lists) reserved(do)
+ ident(puts) string<delimiter(")content(The list is: )inline<delimiter(#{)ident(commify_series)operator(()ident(list)operator(\))delimiter(})>content(.)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_4.3)
+comment(# (note: AFAIK Ruby doesn't allow gory change of Array length\))
+comment(# grow the array by assigning nil to past the end of array)
+ident(ary)operator([)ident(new_size)operator(-)integer(1)operator(]) operator(=) pre_constant(nil)
+comment(# shrink the array by slicing it down)
+ident(ary)operator(.)ident(slice!)operator(()ident(new_size)operator(..)operator(-)integer(1)operator(\))
+comment(# init the array with given size)
+constant(Array)operator(.)ident(new)operator(()ident(number_of_elems)operator(\))
+comment(# assign to an element past the original end enlarges the array)
+ident(ary)operator([)ident(index_new_last_elem)operator(]) operator(=) ident(value)
+
+reserved(def) method(what_about_that_array)operator(()ident(a)operator(\))
+ ident(print) string<delimiter(")content(The array now has )delimiter(")>operator(,) ident(a)operator(.)ident(size)operator(,) string<delimiter(")content( elements.)char(\\n)delimiter(")>
+ comment(# Index of last element is not really interesting in Ruby)
+ ident(print) string<delimiter(")content(Element #3 is `)inline<delimiter(#{)ident(a)operator([)integer(3)operator(])delimiter(})>content('.)char(\\n)delimiter(")>
+reserved(end)
+ident(people) operator(=) string<delimiter(%w()content(Crosby Stills Nash Young)delimiter(\))>
+ident(what_about_that_array)operator(()ident(people)operator(\))
+
+
+comment(# @@PLEAC@@_4.4)
+comment(# OO style)
+ident(bad_users)operator(.)ident(each) operator({) operator(|)ident(user)operator(|)
+ ident(complain)operator(()ident(user)operator(\))
+operator(})
+comment(# or, functional style)
+reserved(for) ident(user) reserved(in) ident(bad_users)
+ ident(complain)operator(()ident(user)operator(\))
+reserved(end)
+
+reserved(for) ident(var) reserved(in) constant(ENV)operator(.)ident(keys)operator(.)ident(sort)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(var)delimiter(})>content(=)inline<delimiter(#{)constant(ENV)operator([)ident(var)operator(])delimiter(})>delimiter(")>
+reserved(end)
+
+reserved(for) ident(user) reserved(in) ident(all_users)
+ ident(disk_space) operator(=) ident(get_usage)operator(()ident(user)operator(\))
+ reserved(if) operator(()ident(disk_space) operator(>) constant(MAX_QUOTA)operator(\))
+ ident(complain)operator(()ident(user)operator(\))
+ reserved(end)
+reserved(end)
+
+reserved(for) ident(l) reserved(in) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(who)delimiter(")>operator(\))operator(.)ident(readlines)
+ ident(print) ident(l) reserved(if) ident(l) operator(=)operator(~) regexp<delimiter(/)content(^gc)delimiter(/)>
+reserved(end)
+
+comment(# we can mimic the obfuscated Perl way)
+reserved(while) ident(fh)operator(.)ident(gets) comment(# $_ is set to the line just read)
+ ident(chomp) comment(# $_ has a trailing \\n removed, if it had one)
+ ident(split)operator(.)ident(each) operator({) operator(|)ident(w)operator(|) comment(# $_ is split on whitespace)
+ comment(# but $_ is not set to each chunk as in Perl)
+ ident(print) ident(w)operator(.)ident(reverse)
+ operator(})
+reserved(end)
+comment(# ...or use a cleaner way)
+reserved(for) ident(l) reserved(in) ident(fh)operator(.)ident(readlines)
+ ident(l)operator(.)ident(chomp)operator(.)ident(split)operator(.)ident(each) operator({) operator(|)ident(w)operator(|) ident(print) ident(w)operator(.)ident(reverse) operator(})
+reserved(end)
+
+comment(# same drawback as in problem 1.4, we can't mutate a Numeric...)
+ident(array)operator(.)ident(collect!) operator({) operator(|)ident(v)operator(|) ident(v) operator(-) integer(1) operator(})
+
+ident(a) operator(=) operator([) operator(.)integer(5)operator(,) integer(3) operator(])operator(;) ident(b) operator(=) operator([) integer(0)operator(,) integer(1) operator(])
+reserved(for) ident(ary) reserved(in) operator([) ident(a)operator(,) ident(b) operator(])
+ ident(ary)operator(.)ident(collect!) operator({) operator(|)ident(v)operator(|) ident(v) operator(*) integer(7) operator(})
+reserved(end)
+ident(puts) string<delimiter(")inline<delimiter(#{)ident(a)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>content( )inline<delimiter(#{)ident(b)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>delimiter(")>
+
+comment(# we can mutate Strings, cool; we need a trick for the scalar)
+reserved(for) ident(ary) reserved(in) operator([) operator([) ident(scalar) operator(])operator(,) ident(array)operator(,) ident(hash)operator(.)ident(values) operator(])
+ ident(ary)operator(.)ident(each) operator({) operator(|)ident(v)operator(|) ident(v)operator(.)ident(strip!) operator(}) comment(# String#strip rules :\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_4.5)
+comment(# not relevant in Ruby since we have always references)
+reserved(for) ident(item) reserved(in) ident(array)
+ comment(# do somethingh with item)
+reserved(end)
+
+
+comment(# @@PLEAC@@_4.6)
+ident(unique) operator(=) ident(list)operator(.)ident(uniq)
+
+comment(# generate a list of users logged in, removing duplicates)
+ident(users) operator(=) shell<delimiter(`)content(who)delimiter(`)>operator(.)ident(collect) operator({) operator(|)ident(l)operator(|) ident(l) operator(=)operator(~) regexp<delimiter(/)content(()char(\\w)content(+\))delimiter(/)>operator(;) global_variable($1) operator(})operator(.)ident(sort)operator(.)ident(uniq)
+ident(puts)operator(()string<delimiter(")content(users logged in: )inline<delimiter(#{)ident(commify_series)operator(()ident(users)operator(\))delimiter(})>delimiter(")>operator(\)) comment(# see 4.2 for commify_series)
+
+
+comment(# @@PLEAC@@_4.7)
+ident(a) operator(-) ident(b)
+comment(# [ 1, 1, 2, 2, 3, 3, 3, 4, 5 ] - [ 1, 2, 4 ] -> [3, 5])
+
+
+comment(# @@PLEAC@@_4.8)
+ident(union) operator(=) ident(a) operator(|) ident(b)
+ident(intersection) operator(=) ident(a) operator(&) ident(b)
+ident(difference) operator(=) ident(a) operator(-) ident(b)
+
+
+comment(# @@PLEAC@@_4.9)
+ident(array1)operator(.)ident(concat)operator(()ident(array2)operator(\))
+comment(# if you will assign to another object, better use:)
+ident(new_ary) operator(=) ident(array1) operator(+) ident(array2)
+
+ident(members) operator(=) operator([) string<delimiter(")content(Time)delimiter(")>operator(,) string<delimiter(")content(Flies)delimiter(")> operator(])
+ident(initiates) operator(=) operator([) string<delimiter(")content(An)delimiter(")>operator(,) string<delimiter(")content(Arrow)delimiter(")> operator(])
+ident(members) operator(+)operator(=) ident(initiates)
+
+ident(members) operator(=) operator([) string<delimiter(")content(Time)delimiter(")>operator(,) string<delimiter(")content(Flies)delimiter(")> operator(])
+ident(initiates) operator(=) operator([) string<delimiter(")content(An)delimiter(")>operator(,) string<delimiter(")content(Arrow)delimiter(")> operator(])
+ident(members)operator([)integer(2)operator(,)integer(0)operator(]) operator(=) operator([) string<delimiter(")content(Like)delimiter(")>operator(,) ident(initiates) operator(])operator(.)ident(flatten)
+
+ident(members)operator([)integer(0)operator(]) operator(=) string<delimiter(")content(Fruit)delimiter(")>
+ident(members)operator([)integer(3)operator(,)integer(2)operator(]) operator(=) string<delimiter(")content(A)delimiter(")>operator(,) string<delimiter(")content(Banana)delimiter(")>
+
+
+comment(# @@PLEAC@@_4.10)
+ident(reversed) operator(=) ident(ary)operator(.)ident(reverse)
+
+ident(ary)operator(.)ident(reverse_each) operator({) operator(|)ident(e)operator(|)
+ comment(# do something with e)
+operator(})
+
+ident(descending) operator(=) ident(ary)operator(.)ident(sort)operator(.)ident(reverse)
+ident(descending) operator(=) ident(ary)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(b) operator(<=>) ident(a) operator(})
+
+
+comment(# @@PLEAC@@_4.11)
+comment(# remove n elements from front of ary (shift n\))
+ident(front) operator(=) ident(ary)operator(.)ident(slice!)operator(()integer(0)operator(,) ident(n)operator(\))
+
+comment(# remove n elements from the end of ary (pop n\))
+ident(end_) operator(=) ident(ary)operator(.)ident(slice!)operator(()operator(-)ident(n) operator(..) operator(-)integer(1)operator(\))
+
+comment(# let's extend the Array class, to make that useful)
+reserved(class) class(Array)
+ reserved(def) method(shift2)operator(()operator(\))
+ ident(slice!)operator(()integer(0) operator(..) integer(1)operator(\)) comment(# more symetric with pop2...)
+ reserved(end)
+ reserved(def) method(pop2)operator(()operator(\))
+ ident(slice!)operator(()operator(-)integer(2) operator(..) operator(-)integer(1)operator(\))
+ reserved(end)
+reserved(end)
+
+ident(friends) operator(=) string<delimiter(%w()content(Peter Paul Mary Jim Tim)delimiter(\))>
+ident(this)operator(,) ident(that) operator(=) ident(friends)operator(.)ident(shift2)
+
+ident(beverages) operator(=) string<delimiter(%w()content(Dew Jolt Cola Sprite Fresca)delimiter(\))>
+ident(pair) operator(=) ident(beverages)operator(.)ident(pop2)
+
+
+comment(# @@PLEAC@@_4.12)
+comment(# use Enumerable#detect (or the synonym Enumerable#find\))
+ident(highest_eng) operator(=) ident(employees)operator(.)ident(detect) operator({) operator(|)ident(emp)operator(|) ident(emp)operator(.)ident(category) operator(==) string<delimiter(')content(engineer)delimiter(')> operator(})
+
+
+comment(# @@PLEAC@@_4.13)
+comment(# use Enumerable#select (or the synonym Enumerable#find_all\))
+ident(bigs) operator(=) ident(nums)operator(.)ident(select) operator({) operator(|)ident(i)operator(|) ident(i) operator(>) integer(1_000_000) operator(})
+ident(pigs) operator(=) ident(users)operator(.)ident(keys)operator(.)ident(select) operator({) operator(|)ident(k)operator(|) ident(users)operator([)ident(k)operator(]) operator(>) float(1e7) operator(})
+
+ident(matching) operator(=) shell<delimiter(`)content(who)delimiter(`)>operator(.)ident(select) operator({) operator(|)ident(u)operator(|) ident(u) operator(=)operator(~) regexp<delimiter(/)content(^gnat )delimiter(/)> operator(})
+
+ident(engineers) operator(=) ident(employees)operator(.)ident(select) operator({) operator(|)ident(e)operator(|) ident(e)operator(.)ident(position) operator(==) string<delimiter(')content(Engineer)delimiter(')> operator(})
+
+ident(secondary_assistance) operator(=) ident(applicants)operator(.)ident(select) operator({) operator(|)ident(a)operator(|)
+ ident(a)operator(.)ident(income) operator(>)operator(=) integer(26_000) operator(&&) ident(a)operator(.)ident(income) operator(<) integer(30_000)
+operator(})
+
+
+comment(# @@PLEAC@@_4.14)
+comment(# normally you would have an array of Numeric (Float or)
+comment(# Fixnum or Bignum\), so you would use:)
+ident(sorted) operator(=) ident(unsorted)operator(.)ident(sort)
+comment(# if you have strings representing Integers or Floats)
+comment(# you may specify another sort method:)
+ident(sorted) operator(=) ident(unsorted)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator(.)ident(to_f) operator(<=>) ident(b)operator(.)ident(to_f) operator(})
+
+comment(# let's use the list of my own PID's)
+shell<delimiter(`)content(ps ux)delimiter(`)>operator(.)ident(split)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\))operator([)integer(1)operator(..)operator(-)integer(1)operator(])operator(.)
+ ident(select) operator({) operator(|)ident(i)operator(|) ident(i) operator(=)operator(~) regexp<delimiter(/)content(^)inline<delimiter(#{)constant(ENV)operator([)string<delimiter(')content(USER)delimiter(')>operator(])delimiter(})>delimiter(/)> operator(})operator(.)
+ ident(collect) operator({) operator(|)ident(i)operator(|) ident(i)operator(.)ident(split)operator([)integer(1)operator(]) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator(.)ident(to_i) operator(<=>) ident(b)operator(.)ident(to_i) operator(})operator(.)ident(each) operator({) operator(|)ident(i)operator(|) ident(puts) ident(i) operator(})
+ident(puts) string<delimiter(")content(Select a process ID to kill:)delimiter(")>
+ident(pid) operator(=) ident(gets)operator(.)ident(chomp)
+ident(raise) string<delimiter(")content(Exiting ... )char(\\n)delimiter(")> reserved(unless) ident(pid) operator(&&) ident(pid) operator(=)operator(~) regexp<delimiter(/)content(^)char(\\d)content(+$)delimiter(/)>
+constant(Process)operator(.)ident(kill)operator(()string<delimiter(')content(TERM)delimiter(')>operator(,) ident(pid)operator(.)ident(to_i)operator(\))
+ident(sleep) integer(2)
+constant(Process)operator(.)ident(kill)operator(()string<delimiter(')content(KILL)delimiter(')>operator(,) ident(pid)operator(.)ident(to_i)operator(\))
+
+ident(descending) operator(=) ident(unsorted)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(b)operator(.)ident(to_f) operator(<=>) ident(a)operator(.)ident(to_f) operator(})
+
+
+comment(# @@PLEAC@@_4.15)
+ident(ordered) operator(=) ident(unordered)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(compare)operator(()ident(a)operator(,)ident(b)operator(\)) operator(})
+
+ident(precomputed) operator(=) ident(unordered)operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) operator([)ident(compute)operator(,) ident(e)operator(]) operator(})
+ident(ordered_precomputed) operator(=) ident(precomputed)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})
+ident(ordered) operator(=) ident(ordered_precomputed)operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) ident(e)operator([)integer(1)operator(]) operator(})
+
+ident(ordered) operator(=) ident(unordered)operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) operator([)ident(compute)operator(,) ident(e)operator(]) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})operator(.)
+ ident(collect) operator({) operator(|)ident(e)operator(|) ident(e)operator([)integer(1)operator(]) operator(})
+
+reserved(for) ident(employee) reserved(in) ident(employees)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator(.)ident(name) operator(<=>) ident(b)operator(.)ident(name) operator(})
+ ident(print) ident(employee)operator(.)ident(name)operator(,) string<delimiter(")content( earns )char(\\$)content( )delimiter(")>operator(,) ident(employee)operator(.)ident(salary)operator(,) string<delimiter(")char(\\n)delimiter(")>
+reserved(end)
+
+comment(# Beware! `0' is true in Ruby.)
+comment(# For chaining comparisons, you may use Numeric#nonzero?, which)
+comment(# returns num if num is not zero, nil otherwise)
+ident(sorted) operator(=) ident(employees)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) operator(()ident(a)operator(.)ident(name) operator(<=>) ident(b)operator(.)ident(name)operator(\))operator(.)ident(nonzero?) operator(||) ident(b)operator(.)ident(age) operator(<=>) ident(a)operator(.)ident(age) operator(})
+
+ident(users) operator(=) operator([)operator(])
+comment(# getpwent is not wrapped in Ruby... let's fallback)
+constant(IO)operator(.)ident(readlines)operator(()string<delimiter(')content(/etc/passwd)delimiter(')>operator(\))operator(.)ident(each) operator({) operator(|)ident(u)operator(|) ident(users) operator(<<) ident(u)operator(.)ident(split)operator(()string<delimiter(')content(:)delimiter(')>operator(\)) operator(})
+ident(users)operator(.)ident(sort!) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})
+reserved(for) ident(user) reserved(in) ident(users)
+ ident(puts) ident(user)operator([)integer(0)operator(])
+reserved(end)
+
+ident(sorted) operator(=) ident(names)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(1)operator(,) integer(1)operator(]) operator(<=>) ident(b)operator([)integer(1)operator(,) integer(1)operator(]) operator(})
+ident(sorted) operator(=) ident(strings)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator(.)ident(length) operator(<=>) ident(b)operator(.)ident(length) operator(})
+
+comment(# let's show only the compact version)
+ident(ordered) operator(=) ident(strings)operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) operator([)ident(e)operator(.)ident(length)operator(,) ident(e)operator(]) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})operator(.)
+ ident(collect) operator({) operator(|)ident(e)operator(|) ident(e)operator([)integer(1)operator(]) operator(})
+
+ident(ordered) operator(=) ident(strings)operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) operator([)regexp<delimiter(/)char(\\d)content(+)delimiter(/)>operator(.)ident(match)operator(()ident(e)operator(\))operator([)integer(0)operator(])operator(.)ident(to_i)operator(,) ident(e)operator(]) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})operator(.)
+ ident(collect) operator({) operator(|)ident(e)operator(|) ident(e)operator([)integer(1)operator(]) operator(})
+
+ident(print) shell<delimiter(`)content(cat /etc/passwd)delimiter(`)>operator(.)ident(collect) operator({) operator(|)ident(e)operator(|) operator([)ident(e)operator(,) ident(e)operator(.)ident(split)operator(()string<delimiter(')content(:)delimiter(')>operator(\))operator(.)ident(indexes)operator(()integer(3)operator(,)integer(2)operator(,)integer(0)operator(\))operator(])operator(.)ident(flatten) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) operator(()ident(a)operator([)integer(1)operator(]) operator(<=>) ident(b)operator([)integer(1)operator(])operator(\))operator(.)ident(nonzero?) operator(||) operator(()ident(a)operator([)integer(2)operator(]) operator(<=>) ident(b)operator([)integer(2)operator(])operator(\))operator(.)ident(nonzero?) operator(||) ident(a)operator([)integer(3)operator(]) operator(<=>) ident(b)operator([)integer(3)operator(]) operator(})operator(.)
+ ident(collect) operator({) operator(|)ident(e)operator(|) ident(e)operator([)integer(0)operator(]) operator(})
+
+
+comment(# @@PLEAC@@_4.16)
+ident(circular)operator(.)ident(unshift)operator(()ident(circular)operator(.)ident(pop)operator(\)) comment(# the last shall be first)
+ident(circular)operator(.)ident(push)operator(()ident(circular)operator(.)ident(shift)operator(\)) comment(# and vice versa)
+
+reserved(def) method(grab_and_rotate)operator(()ident(l)operator(\))
+ ident(l)operator(.)ident(push)operator(()ident(ret) operator(=) ident(l)operator(.)ident(shift)operator(\))
+ ident(ret)
+reserved(end)
+
+ident(processes) operator(=) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5)operator(])
+reserved(while) operator(()integer(1)operator(\))
+ ident(process) operator(=) ident(grab_and_rotate)operator(()ident(processes)operator(\))
+ ident(puts) string<delimiter(")content(Handling process )inline<delimiter(#{)ident(process)delimiter(})>delimiter(")>
+ ident(sleep) integer(1)
+reserved(end)
+
+
+comment(# @@PLEAC@@_4.17)
+reserved(def) method(fisher_yates_shuffle)operator(()ident(a)operator(\))
+ operator(()ident(a)operator(.)ident(size)operator(-)integer(1)operator(\))operator(.)ident(downto)operator(()integer(1)operator(\)) operator({) operator(|)ident(i)operator(|)
+ ident(j) operator(=) ident(rand)operator(()ident(i)operator(+)integer(1)operator(\))
+ ident(a)operator([)ident(i)operator(])operator(,) ident(a)operator([)ident(j)operator(]) operator(=) ident(a)operator([)ident(j)operator(])operator(,) ident(a)operator([)ident(i)operator(]) reserved(if) ident(i) operator(!)operator(=) ident(j)
+ operator(})
+reserved(end)
+
+reserved(def) method(naive_shuffle)operator(()ident(a)operator(\))
+ reserved(for) ident(i) reserved(in) integer(0)operator(...)ident(a)operator(.)ident(size)
+ ident(j) operator(=) ident(rand)operator(()ident(a)operator(.)ident(size)operator(\))
+ ident(a)operator([)ident(i)operator(])operator(,) ident(a)operator([)ident(j)operator(]) operator(=) ident(a)operator([)ident(j)operator(])operator(,) ident(a)operator([)ident(i)operator(])
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_4.18)
+comment(#!/usr/bin/env ruby)
+comment(# example 4-2 words)
+comment(# words - gather lines, present in colums)
+
+comment(# class to encapsulate the word formatting from the input)
+reserved(class) class(WordFormatter)
+ reserved(def) method(initialize)operator(()ident(cols)operator(\))
+ instance_variable(@cols) operator(=) ident(cols)
+ reserved(end)
+
+ comment(# helper to return the length of the longest word in the wordlist)
+ reserved(def) method(maxlen)operator(()ident(wordlist)operator(\))
+ ident(max) operator(=) integer(1)
+ reserved(for) ident(word) reserved(in) ident(wordlist)
+ reserved(if) ident(word)operator(.)ident(length) operator(>) ident(max)
+ ident(max) operator(=) ident(word)operator(.)ident(length)
+ reserved(end)
+ reserved(end)
+ ident(max)
+ reserved(end)
+
+ comment(# process the wordlist and print it formmated into columns)
+ reserved(def) method(output)operator(()ident(wordlist)operator(\))
+ ident(collen) operator(=) ident(maxlen)operator(()ident(wordlist)operator(\)) operator(+) integer(1)
+ ident(columns) operator(=) instance_variable(@cols) operator(/) ident(collen)
+ ident(columns) operator(=) integer(1) reserved(if) ident(columns) operator(==) integer(0)
+ ident(rows) operator(=) operator(()ident(wordlist)operator(.)ident(length) operator(+) ident(columns) operator(-) integer(1)operator(\)) operator(/) ident(columns)
+ comment(# now process each item, picking out proper piece for this position)
+ integer(0)operator(.)ident(upto)operator(()ident(rows) operator(*) ident(columns) operator(-) integer(1)operator(\)) operator({) operator(|)ident(item)operator(|)
+ ident(target) operator(=) operator(()ident(item) operator(%) ident(columns)operator(\)) operator(*) ident(rows) operator(+) operator(()ident(item) operator(/) ident(columns)operator(\))
+ ident(eol) operator(=) operator(()operator(()ident(item)operator(+)integer(1)operator(\)) operator(%) ident(columns) operator(==) integer(0)operator(\))
+ ident(piece) operator(=) ident(wordlist)operator([)ident(target)operator(]) operator(||) string<delimiter(")delimiter(")>
+ ident(piece) operator(=) ident(piece)operator(.)ident(ljust)operator(()ident(collen)operator(\)) reserved(unless) ident(eol)
+ ident(print) ident(piece)
+ ident(puts) reserved(if) ident(eol)
+ operator(})
+ comment(# no need to finish it up, because eol is always true for the last element)
+ reserved(end)
+reserved(end)
+
+comment(# get nr of chars that fit in window or console, see PLEAC 15.4)
+comment(# not portable -- linux only (?\))
+reserved(def) method(getWinCharWidth)operator(()operator(\))
+ ident(buf) operator(=) string<delimiter(")char(\\0)delimiter(")> operator(*) integer(8)
+ global_variable($stdout)operator(.)ident(ioctl)operator(()integer(0x5413)operator(,) ident(buf)operator(\))
+ ident(ws_row)operator(,) ident(ws_col)operator(,) ident(ws_xpixel)operator(,) ident(ws_ypixel) operator(=) ident(buf)operator(.)ident(unpack)operator(()string<delimiter(")content($4)delimiter(")>operator(\))
+ ident(ws_col) operator(||) integer(80)
+reserved(rescue)
+ integer(80)
+reserved(end)
+
+comment(# main program)
+ident(cols) operator(=) ident(getWinCharWidth)operator(()operator(\))
+ident(formatter) operator(=) constant(WordFormatter)operator(.)ident(new)operator(()ident(cols)operator(\))
+ident(words) operator(=) ident(readlines)operator(()operator(\))
+ident(words)operator(.)ident(collect!) operator({) operator(|)ident(line)operator(|)
+ ident(line)operator(.)ident(chomp)
+operator(})
+ident(formatter)operator(.)ident(output)operator(()ident(words)operator(\))
+
+
+comment(# @@PLEAC@@_4.19)
+comment(# In ruby, Fixnum's are automatically converted to Bignum's when)
+comment(# needed, so there is no need for an extra module)
+reserved(def) method(factorial)operator(()ident(n)operator(\))
+ ident(s) operator(=) integer(1)
+ reserved(while) ident(n) operator(>) integer(0)
+ ident(s) operator(*)operator(=) ident(n)
+ ident(n) operator(-)operator(=) integer(1)
+ reserved(end)
+ ident(s)
+reserved(end)
+
+ident(puts) ident(factorial)operator(()integer(500)operator(\))
+
+comment(#---------------------------------------------------------)
+comment(# Example 4-3. tsc-permute)
+comment(# tsc_permute: permute each word of input)
+reserved(def) method(permute)operator(()ident(items)operator(,) ident(perms)operator(\))
+ reserved(unless) ident(items)operator(.)ident(length) operator(>) integer(0)
+ ident(puts) ident(perms)operator(.)ident(join)operator(()string<delimiter(")content( )delimiter(")>operator(\))
+ reserved(else)
+ reserved(for) ident(i) reserved(in) ident(items)
+ ident(newitems) operator(=) ident(items)operator(.)ident(dup)
+ ident(newperms) operator(=) ident(perms)operator(.)ident(dup)
+ ident(newperms)operator(.)ident(unshift)operator(()ident(newitems)operator(.)ident(delete)operator(()ident(i)operator(\))operator(\))
+ ident(permute)operator(()ident(newitems)operator(,) ident(newperms)operator(\))
+ reserved(end)
+ reserved(end)
+reserved(end)
+comment(# In ruby the main program must be after all definitions it is using)
+ident(permute)operator(()pre_constant(ARGV)operator(,) operator([)operator(])operator(\))
+
+comment(#---------------------------------------------------------)
+comment(# mjd_permute: permute each word of input)
+
+reserved(def) method(factorial)operator(()ident(n)operator(\))
+ ident(s) operator(=) integer(1)
+ reserved(while) ident(n) operator(>) integer(0)
+ ident(s) operator(*)operator(=) ident(n)
+ ident(n) operator(-)operator(=) integer(1)
+ reserved(end)
+ ident(s)
+reserved(end)
+
+comment(# we use a class with a class variable store the private cache)
+comment(# for the results of the factorial function.)
+reserved(class) class(Factorial)
+ class_variable(@@fact) operator(=) operator([) integer(1) operator(])
+ reserved(def) constant(Factorial)operator(.)ident(compute)operator(()ident(n)operator(\))
+ reserved(if) class_variable(@@fact)operator([)ident(n)operator(])
+ class_variable(@@fact)operator([)ident(n)operator(])
+ reserved(else)
+ class_variable(@@fact)operator([)ident(n)operator(]) operator(=) ident(n) operator(*) constant(Factorial)operator(.)ident(compute)operator(()ident(n) operator(-) integer(1)operator(\))
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+comment(#---------------------------------------------------------)
+comment(# Example 4-4- mjd-permute)
+comment(# n2pat(n, len\): produce the N-th pattern of length len)
+
+comment(# We must use a lower case letter as parameter N, otherwise it is)
+comment(# handled as constant Length is the length of the resulting)
+comment(# array, not the index of the last element (length -1\) like in)
+comment(# the perl example.)
+reserved(def) method(n2pat)operator(()ident(n)operator(,) ident(length)operator(\))
+ ident(pat) operator(=) operator([)operator(])
+ ident(i) operator(=) integer(1)
+ reserved(while) ident(i) operator(<=) ident(length)
+ ident(pat)operator(.)ident(push)operator(()ident(n) operator(%) ident(i)operator(\))
+ ident(n) regexp<delimiter(/)content(= i
+ i += 1
+ end
+ pat
+end
+
+# pat2perm(pat\): turn pattern returned by n2pat(\) into
+# permutation of integers.
+def pat2perm(pat\)
+ source = (0 .. pat.length - 1\).to_a
+ perm = []
+ perm.push(source.slice!(pat.pop\)\) while pat.length > 0
+ perm
+end
+
+def n2perm(n, len\)
+ pat2perm(n2pat(n,len\)\)
+end
+
+# In ruby the main program must be after all definitions
+while gets
+ data = split
+ # the perl solution has used $#data, which is length-1
+ num_permutations = Factorial.compute(data.length(\)\)
+ 0.upto(num_permutations - 1\) do |i|
+ # in ruby we can not use an array as selector for an array
+ # but by exchanging the two arrays, we can use the collect method
+ # which returns an array with the result of all block invocations
+ permutation = n2perm(i, data.length\).collect {
+ |j| data[j]
+ }
+ puts permutation.join(" "\)
+ end
+end
+
+
+# @@PLEAC@@_5.0
+age = { "Nat", 24,
+ "Jules", 25,
+ "Josh", 17 }
+
+age["Nat"] = 24
+age["Jules"] = 25
+age["Josh"] = 17
+
+food_color = {
+ "Apple" => "red",
+ "Banana" => "yellow",
+ "Lemon" => "yellow",
+ "Carrot" => "orange"
+ }
+
+# In Ruby, you cannot avoid the double or simple quoting
+# while manipulatin hashes
+
+
+# @@PLEAC@@_5.1
+hash[key] = value
+
+food_color["Raspberry"] = "pink"
+puts "Known foods:", food_color.keys
+
+
+# @@PLEAC@@_5.2
+# does hash have a value for key ?
+if (hash.has_key?(key\)\)
+ # it exists
+else
+ # it doesn't
+end
+
+[ "Banana", "Martini" ].each { |name|
+ print name, " is a ", food_color.has_key?(name\) ? "food" : "drink", ")char(\\n)content("
+}
+
+age = {}
+age['Toddler'] = 3
+age['Unborn'] = 0
+age['Phantasm'] = nil
+
+for thing in ['Toddler', 'Unborn', 'Phantasm', 'Relic']
+ print ")inline<delimiter(#{)ident(thing)delimiter(})>content(: "
+ print "Has-key " if age.has_key?(thing\)
+ print "True " if age[thing]
+ print "Nonzero " if age[thing] && age[thing].nonzero?
+ print ")char(\\n)content("
+end
+
+#=>
+# Toddler: Has-key True Nonzero
+# Unborn: Has-key True
+# Phantasm: Has-key
+# Relic:
+
+# You use Hash#has_key? when you use Perl's exists -> it checks
+# for existence of a key in a hash.
+# All Numeric are "True" in ruby, so the test doesn't have the
+# same semantics as in Perl; you would use Numeric#nonzero? to
+# achieve the same semantics (false if 0, true otherwise\).
+
+
+# @@PLEAC@@_5.3
+food_color.delete("Banana"\)
+
+
+# @@PLEAC@@_5.4
+hash.each { |key, value|
+ # do something with key and value
+}
+
+hash.each_key { |key|
+ # do something with key
+}
+
+food_color.each { |food, color|
+ puts ")inline<delimiter(#{)ident(food)delimiter(})>content( is )inline<delimiter(#{)ident(color)delimiter(})>content("
+}
+
+food_color.each_key { |food|
+ puts ")inline<delimiter(#{)ident(food)delimiter(})>content( is )inline<delimiter(#{)ident(food_color)operator([)ident(food)operator(])delimiter(})>content("
+}
+
+# IMO this demonstrates that OO style is by far more readable
+food_color.keys.sort.each { |food|
+ puts ")inline<delimiter(#{)ident(food)delimiter(})>content( is )inline<delimiter(#{)ident(food_color)operator([)ident(food)operator(])delimiter(})>content(."
+}
+
+#-----------------------------
+#!)delimiter(/)modifier(us)>ident(r)operator(/)ident(bin)operator(/)ident(ruby)
+comment(# countfrom - count number of messages from each sender)
+
+comment(# Default value is 0)
+ident(from) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(0)operator(\))
+reserved(while) ident(gets)
+ regexp<delimiter(/)content(^From: (.*\))delimiter(/)> reserved(and) ident(from)operator([)global_variable($1)operator(]) operator(+)operator(=) integer(1)
+reserved(end)
+
+comment(# More useful to sort by number of received mail by person)
+ident(from)operator(.)ident(sort) operator({)operator(|)ident(a)operator(,)ident(b)operator(|) ident(b)operator([)integer(1)operator(])operator(<=>)ident(a)operator([)integer(1)operator(])operator(})operator(.)ident(each) operator({) operator(|)ident(v)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(v)operator([)integer(1)operator(])delimiter(})>content(: )inline<delimiter(#{)ident(v)operator([)integer(0)operator(])delimiter(})>delimiter(")>
+operator(})
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_5.5)
+comment(# You may use the built-in 'inspect' method this way:)
+ident(p) ident(hash)
+
+comment(# Or do it the Cookbook way:)
+ident(hash)operator(.)ident(each) operator({) operator(|)ident(k)operator(,)ident(v)operator(|) ident(puts) string<delimiter(")inline<delimiter(#{)ident(k)delimiter(})>content( => )inline<delimiter(#{)ident(v)delimiter(})>delimiter(")> operator(})
+
+comment(# Sorted by keys)
+ident(hash)operator(.)ident(sort)operator(.)ident(each) operator({) operator(|)ident(e)operator(|) ident(puts) string<delimiter(")inline<delimiter(#{)ident(e)operator([)integer(0)operator(])delimiter(})>content( => )inline<delimiter(#{)ident(e)operator([)integer(1)operator(])delimiter(})>delimiter(")> operator(})
+comment(# Sorted by values)
+ident(hash)operator(.)ident(sort)operator({)operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(1)operator(])operator(<=>)ident(b)operator([)integer(1)operator(])operator(})operator(.)ident(each) operator({) operator(|)ident(e)operator(|) ident(puts) string<delimiter(")inline<delimiter(#{)ident(e)operator([)integer(0)operator(])delimiter(})>content( => )inline<delimiter(#{)ident(e)operator([)integer(1)operator(])delimiter(})>delimiter(")> operator(})
+
+
+comment(# @@PLEAC@@_5.7)
+ident(ttys) operator(=) constant(Hash)operator(.)ident(new)
+reserved(for) ident(i) reserved(in) shell<delimiter(`)content(who)delimiter(`)>
+ ident(user)operator(,) ident(tty) operator(=) ident(i)operator(.)ident(split)
+ operator(()ident(ttys)operator([)ident(user)operator(]) operator(||)operator(=) operator([)operator(])operator(\)) operator(<<) ident(tty) comment(# see problems_ruby for more infos)
+reserved(end)
+ident(ttys)operator(.)ident(keys)operator(.)ident(sort)operator(.)ident(each) operator({) operator(|)ident(k)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(k)delimiter(})>content(: )inline<delimiter(#{)ident(commify_series)operator(()ident(ttys)operator([)ident(k)operator(])operator(\))delimiter(})>delimiter(")> comment(# from 4.2)
+operator(})
+
+
+comment(# @@PLEAC@@_5.8)
+ident(surname) operator(=) operator({) string<delimiter(")content(Mickey)delimiter(")> operator(=)operator(>) string<delimiter(")content(Mantle)delimiter(")>operator(,) string<delimiter(")content(Babe)delimiter(")> operator(=)operator(>) string<delimiter(")content(Ruth)delimiter(")> operator(})
+ident(puts) ident(surname)operator(.)ident(index)operator(()string<delimiter(")content(Mantle)delimiter(")>operator(\))
+
+comment(# If you really needed to 'invert' the whole hash, use Hash#invert)
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# foodfind - find match for food or color)
+
+ident(given) operator(=) pre_constant(ARGV)operator(.)ident(shift) reserved(or) ident(raise) string<delimiter(")content(usage: foodfind food_or_color)delimiter(")>
+
+ident(color) operator(=) operator({)
+ string<delimiter(")content(Apple)delimiter(")> operator(=)operator(>) string<delimiter(")content(red)delimiter(")>operator(,)
+ string<delimiter(")content(Banana)delimiter(")> operator(=)operator(>) string<delimiter(")content(yellow)delimiter(")>operator(,)
+ string<delimiter(")content(Lemon)delimiter(")> operator(=)operator(>) string<delimiter(")content(yellow)delimiter(")>operator(,)
+ string<delimiter(")content(Carrot)delimiter(")> operator(=)operator(>) string<delimiter(")content(orange)delimiter(")>operator(,)
+operator(})
+
+reserved(if) operator(()ident(color)operator(.)ident(has_key?)operator(()ident(given)operator(\))operator(\))
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(given)delimiter(})>content( is a food with color )inline<delimiter(#{)ident(color)operator([)ident(given)operator(])delimiter(})>content(.)delimiter(")>
+reserved(end)
+reserved(if) operator(()ident(color)operator(.)ident(has_value?)operator(()ident(given)operator(\))operator(\))
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(color)operator(.)ident(index)operator(()ident(given)operator(\))delimiter(})>content( is a food with color )inline<delimiter(#{)ident(given)delimiter(})>content(.)delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_5.9)
+comment(# Sorted by keys (Hash#sort gives an Array of pairs made of each key,value\))
+ident(food_color)operator(.)ident(sort)operator(.)ident(each) operator({) operator(|)ident(f)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(f)operator([)integer(0)operator(])delimiter(})>content( is )inline<delimiter(#{)ident(f)operator([)integer(1)operator(])delimiter(})>content(.)delimiter(")>
+operator(})
+
+comment(# Sorted by values)
+ident(food_color)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(1)operator(]) operator(<=>) ident(b)operator([)integer(1)operator(]) operator(})operator(.)ident(each) operator({) operator(|)ident(f)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(f)operator([)integer(0)operator(])delimiter(})>content( is )inline<delimiter(#{)ident(f)operator([)integer(1)operator(])delimiter(})>content(.)delimiter(")>
+operator(})
+
+comment(# Sorted by length of values)
+ident(food_color)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(1)operator(])operator(.)ident(length) operator(<=>) ident(b)operator([)integer(1)operator(])operator(.)ident(length) operator(})operator(.)ident(each) operator({) operator(|)ident(f)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(f)operator([)integer(0)operator(])delimiter(})>content( is )inline<delimiter(#{)ident(f)operator([)integer(1)operator(])delimiter(})>content(.)delimiter(")>
+operator(})
+
+
+comment(# @@PLEAC@@_5.10)
+ident(merged) operator(=) ident(a)operator(.)ident(clone)operator(.)ident(update)operator(()ident(b)operator(\)) comment(# because Hash#update changes object in place)
+
+ident(drink_color) operator(=) operator({) string<delimiter(")content(Galliano)delimiter(")> operator(=)operator(>) string<delimiter(")content(yellow)delimiter(")>operator(,) string<delimiter(")content(Mai Tai)delimiter(")> operator(=)operator(>) string<delimiter(")content(blue)delimiter(")> operator(})
+ident(ingested_color) operator(=) ident(drink_color)operator(.)ident(clone)operator(.)ident(update)operator(()ident(food_color)operator(\))
+
+ident(substance_color) operator(=) operator({)operator(})
+reserved(for) ident(i) reserved(in) operator([) ident(food_color)operator(,) ident(drink_color) operator(])
+ ident(i)operator(.)ident(each_key) operator({) operator(|)ident(k)operator(|)
+ reserved(if) ident(substance_color)operator(.)ident(has_key?)operator(()ident(k)operator(\))
+ ident(puts) string<delimiter(")content(Warning: )inline<delimiter(#{)ident(k)delimiter(})>content( seen twice. Using the first definition.)delimiter(")>
+ reserved(next)
+ reserved(end)
+ ident(substance_color)operator([)ident(k)operator(]) operator(=) integer(1)
+ operator(})
+reserved(end)
+
+
+comment(# @@PLEAC@@_5.11)
+ident(common) operator(=) ident(hash1)operator(.)ident(keys) operator(&) ident(hash2)operator(.)ident(keys)
+
+ident(this_not_that) operator(=) ident(hash1)operator(.)ident(keys) operator(-) ident(hash2)operator(.)ident(keys)
+
+
+comment(# @@PLEAC@@_5.12)
+comment(# no problem here, Ruby handles any kind of object for key-ing)
+comment(# (it takes Object#hash, which defaults to Object#id\))
+
+
+comment(# @@PLEAC@@_5.13)
+comment(# AFAIK, not possible in Ruby)
+
+
+comment(# @@PLEAC@@_5.14)
+comment(# Be careful, the following is possible only because Fixnum objects are)
+comment(# special (documentation says: there is effectively only one Fixnum object)
+comment(# instance for any given integer value\).)
+ident(count) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(0)operator(\))
+ident(array)operator(.)ident(each) operator({) operator(|)ident(e)operator(|)
+ ident(count)operator([)ident(e)operator(]) operator(+)operator(=) integer(1)
+operator(})
+
+
+comment(# @@PLEAC@@_5.15)
+ident(father) operator(=) operator({)
+ string<delimiter(")content(Cain)delimiter(")> operator(,) string<delimiter(")content(Adam)delimiter(")>operator(,)
+ string<delimiter(")content(Abel)delimiter(")> operator(,) string<delimiter(")content(Adam)delimiter(")>operator(,)
+ string<delimiter(")content(Seth)delimiter(")> operator(,) string<delimiter(")content(Adam)delimiter(")>operator(,)
+ string<delimiter(")content(Enoch)delimiter(")> operator(,) string<delimiter(")content(Cain)delimiter(")>operator(,)
+ string<delimiter(")content(Irad)delimiter(")> operator(,) string<delimiter(")content(Enoch)delimiter(")>operator(,)
+ string<delimiter(")content(Mehujael)delimiter(")> operator(,) string<delimiter(")content(Irad)delimiter(")>operator(,)
+ string<delimiter(")content(Methusael)delimiter(")> operator(,) string<delimiter(")content(Mehujael)delimiter(")>operator(,)
+ string<delimiter(")content(Lamech)delimiter(")> operator(,) string<delimiter(")content(Methusael)delimiter(")>operator(,)
+ string<delimiter(")content(Jabal)delimiter(")> operator(,) string<delimiter(")content(Lamech)delimiter(")>operator(,)
+ string<delimiter(")content(Jubal)delimiter(")> operator(,) string<delimiter(")content(Lamech)delimiter(")>operator(,)
+ string<delimiter(")content(Tubalcain)delimiter(")> operator(,) string<delimiter(")content(Lamech)delimiter(")>operator(,)
+ string<delimiter(")content(Enos)delimiter(")> operator(,) string<delimiter(")content(Seth)delimiter(")>operator(,)
+operator(})
+
+reserved(while) ident(gets)
+ ident(chomp)
+ reserved(begin)
+ ident(print) global_variable($_)operator(,) string<delimiter(")content( )delimiter(")>
+ reserved(end) reserved(while) global_variable($_) operator(=) ident(father)operator([)global_variable($_)operator(])
+ ident(puts)
+reserved(end)
+
+ident(children) operator(=) operator({)operator(})
+ident(father)operator(.)ident(each) operator({) operator(|)ident(k)operator(,)ident(v)operator(|)
+ operator(()ident(children)operator([)ident(v)operator(]) operator(||)operator(=) operator([)operator(])operator(\)) operator(<<) ident(k)
+operator(})
+reserved(while) ident(gets)
+ ident(chomp)
+ ident(puts) string<delimiter(")inline<delimiter(#{)global_variable($_)delimiter(})>content( begat )inline<delimiter(#{)operator(()ident(children)operator([)global_variable($_)operator(]) operator(||) operator([)string<delimiter(')content(Nobody)delimiter(')>operator(])operator(\))operator(.)ident(join)operator(()string<delimiter(')content(, )delimiter(')>operator(\))delimiter(})>content(.)char(\\n)delimiter(")>
+reserved(end)
+
+ident(includes) operator(=) operator({)operator(})
+ident(files)operator(.)ident(each) operator({) operator(|)ident(f)operator(|)
+ reserved(begin)
+ reserved(for) ident(l) reserved(in) constant(IO)operator(.)ident(readlines)operator(()ident(f)operator(\))
+ reserved(next) reserved(unless) ident(l) operator(=)operator(~) regexp<delimiter(/)content(^)char(\\s)content(*#)char(\\s)content(*include)char(\\s)content(*<([^>]+\)>)delimiter(/)>
+ operator(()ident(includes)operator([)global_variable($1)operator(]) operator(||)operator(=) operator([)operator(])operator(\)) operator(<<) ident(f)
+ reserved(end)
+ reserved(rescue) constant(SystemCallError)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")escape(#)global_variable($!)content( (skipping\))delimiter(")>
+ reserved(end)
+operator(})
+
+ident(include_free) operator(=) ident(includes)operator(.)ident(values)operator(.)ident(flatten)operator(.)ident(uniq) operator(-) ident(includes)operator(.)ident(keys)
+
+
+comment(# @@PLEAC@@_5.16)
+comment(# dutree - print sorted intented rendition of du output)
+comment(#% dutree)
+comment(#% dutree /usr)
+comment(#% dutree -a)
+comment(#% dutree -a /bin)
+
+comment(# The DuNode class collects all information about a directory,)
+comment(# and provides some convenience methods)
+reserved(class) class(DuNode)
+
+ ident(attr_reader) symbol(:name)
+ ident(attr_accessor) symbol(:size)
+ ident(attr_accessor) symbol(:kids)
+
+ reserved(def) method(initialize)operator(()ident(name)operator(\))
+ instance_variable(@name) operator(=) ident(name)
+ instance_variable(@kids) operator(=) operator([)operator(])
+ instance_variable(@size) operator(=) integer(0)
+ reserved(end)
+
+ comment(# support for sorting nodes with side)
+ reserved(def) method(size_compare)operator(()ident(node2)operator(\))
+ instance_variable(@size) operator(<=>) ident(node2)operator(.)ident(size)
+ reserved(end)
+
+ reserved(def) method(basename)
+ instance_variable(@name)operator(.)ident(sub)operator(()regexp<delimiter(/)content(.*)char(\\/)delimiter(/)>operator(,) string<delimiter(")delimiter(")>operator(\))
+ reserved(end)
+
+ comment(#returns substring before last "/", nil if not there)
+ reserved(def) method(parent)
+ ident(p) operator(=) instance_variable(@name)operator(.)ident(sub)operator(()regexp<delimiter(/)char(\\/)content([^)char(\\/)content(]+$)delimiter(/)>operator(,)string<delimiter(")delimiter(")>operator(\))
+ reserved(if) ident(p) operator(==) instance_variable(@name)
+ pre_constant(nil)
+ reserved(else)
+ ident(p)
+ reserved(end)
+ reserved(end)
+
+reserved(end)
+
+comment(# The DuTree does the acdtual work of)
+comment(# getting the input, parsing it, builging up a tree)
+comment(# and format it for output)
+reserved(class) class(Dutree)
+
+ ident(attr_reader) symbol(:topdir)
+
+ reserved(def) method(initialize)
+ instance_variable(@nodes) operator(=) constant(Hash)operator(.)ident(new)
+ instance_variable(@dirsizes) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(0)operator(\))
+ instance_variable(@kids) operator(=) constant(Hash)operator(.)ident(new)operator(()operator([)operator(])operator(\))
+ reserved(end)
+
+ comment(# get a node by name, create it if it does not exist yet)
+ reserved(def) method(get_create_node)operator(()ident(name)operator(\))
+ reserved(if) instance_variable(@nodes)operator(.)ident(has_key?)operator(()ident(name)operator(\))
+ instance_variable(@nodes)operator([)ident(name)operator(])
+ reserved(else)
+ ident(node) operator(=) constant(DuNode)operator(.)ident(new)operator(()ident(name)operator(\))
+ instance_variable(@nodes)operator([)ident(name)operator(]) operator(=) ident(node)
+ ident(node)
+ reserved(end)
+ reserved(end)
+
+ comment(# run du, read in input, save sizes and kids)
+ comment(# stores last directory read in instance variable topdir)
+ reserved(def) method(input)operator(()ident(arguments)operator(\))
+ ident(name) operator(=) string<delimiter(")delimiter(")>
+ ident(cmd) operator(=) string<delimiter(")content(du )delimiter(")> operator(+) ident(arguments)operator(.)ident(join)operator(()string<delimiter(")content( )delimiter(")>operator(\))
+ constant(IO)operator(.)ident(popen)operator(()ident(cmd)operator(\)) operator({) operator(|)ident(pipe)operator(|)
+ ident(pipe)operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ ident(size)operator(,) ident(name) operator(=) ident(line)operator(.)ident(chomp)operator(.)ident(split)operator(()regexp<delimiter(/)char(\\s)content(+)delimiter(/)>operator(,) integer(2)operator(\))
+ ident(node) operator(=) ident(get_create_node)operator(()ident(name)operator(\))
+ ident(node)operator(.)ident(size) operator(=) ident(size)operator(.)ident(to_i)
+ instance_variable(@nodes)operator([)ident(name)operator(]) operator(=) ident(node)
+ ident(parent) operator(=) ident(node)operator(.)ident(parent)
+ reserved(if) ident(parent)
+ ident(get_create_node)operator(()ident(parent)operator(\))operator(.)ident(kids)operator(.)ident(push)operator(()ident(node)operator(\))
+ reserved(end)
+ operator(})
+ operator(})
+ instance_variable(@topdir) operator(=) instance_variable(@nodes)operator([)ident(name)operator(])
+ reserved(end)
+
+ comment(# figure out how much is taken in each directory)
+ comment(# that isn't stored in the subdirectories. Add a new)
+ comment(# fake kid called "." containing that much.)
+ reserved(def) method(get_dots)operator(()ident(node)operator(\))
+ ident(cursize) operator(=) ident(node)operator(.)ident(size)
+ reserved(for) ident(kid) reserved(in) ident(node)operator(.)ident(kids)
+ ident(cursize) operator(-)operator(=) ident(kid)operator(.)ident(size)
+ ident(get_dots)operator(()ident(kid)operator(\))
+ reserved(end)
+ reserved(if) ident(node)operator(.)ident(size) operator(!)operator(=) ident(cursize)
+ ident(newnode) operator(=) ident(get_create_node)operator(()ident(node)operator(.)ident(name) operator(+) string<delimiter(")content(/.)delimiter(")>operator(\))
+ ident(newnode)operator(.)ident(size) operator(=) ident(cursize)
+ ident(node)operator(.)ident(kids)operator(.)ident(push)operator(()ident(newnode)operator(\))
+ reserved(end)
+ reserved(end)
+
+ comment(# recursively output everything)
+ comment(# passing padding and number width as well)
+ comment(# on recursive calls)
+ reserved(def) method(output)operator(()ident(node)operator(,) ident(prefix)operator(=)string<delimiter(")delimiter(")>operator(,) ident(width)operator(=)integer(0)operator(\))
+ ident(line) operator(=) ident(sprintf)operator(()string<delimiter(")content(%)inline<delimiter(#{)ident(width)delimiter(})>content(d %s)delimiter(")>operator(,) ident(node)operator(.)ident(size)operator(,) ident(node)operator(.)ident(basename)operator(\))
+ ident(puts)operator(()ident(prefix) operator(+) ident(line)operator(\))
+ ident(prefix) operator(+)operator(=) ident(line)operator(.)ident(sub)operator(()regexp<delimiter(/)char(\\d)content( )delimiter(/)>operator(,) string<delimiter(")content(| )delimiter(")>operator(\))
+ ident(prefix)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content([^|])delimiter(/)>operator(,) string<delimiter(")content( )delimiter(")>operator(\))
+ reserved(if) ident(node)operator(.)ident(kids)operator(.)ident(length) operator(>) integer(0) comment(# not a bachelor node)
+ ident(kids) operator(=) ident(node)operator(.)ident(kids)
+ ident(kids)operator(.)ident(sort!) operator({) operator(|)ident(a)operator(,)ident(b)operator(|)
+ ident(b)operator(.)ident(size_compare)operator(()ident(a)operator(\))
+ operator(})
+ ident(width) operator(=) ident(kids)operator([)integer(0)operator(])operator(.)ident(size)operator(.)ident(to_s)operator(.)ident(length)
+ reserved(for) ident(kid) reserved(in) ident(kids)
+ ident(output)operator(()ident(kid)operator(,) ident(prefix)operator(,) ident(width)operator(\))
+ reserved(end)
+ reserved(end)
+ reserved(end)
+
+reserved(end)
+
+ident(tree) operator(=) constant(Dutree)operator(.)ident(new)
+ident(tree)operator(.)ident(input)operator(()pre_constant(ARGV)operator(\))
+ident(tree)operator(.)ident(get_dots)operator(()ident(tree)operator(.)ident(topdir)operator(\))
+ident(tree)operator(.)ident(output)operator(()ident(tree)operator(.)ident(topdir)operator(\))
+
+
+comment(# @@PLEAC@@_6.0)
+comment(# The verbose version are match, sub, gsub, sub! and gsub!;)
+comment(# pattern needs to be a Regexp object; it yields a MatchData)
+comment(# object.)
+ident(pattern)operator(.)ident(match)operator(()ident(string)operator(\))
+ident(string)operator(.)ident(sub)operator(()ident(pattern)operator(,) ident(replacement)operator(\))
+ident(string)operator(.)ident(gsub)operator(()ident(pattern)operator(,) ident(replacement)operator(\))
+comment(# As usual in Ruby, sub! does the same as sub but also modifies)
+comment(# the object, the same for gsub!/gsub.)
+
+comment(# Sugared syntax yields the position of the match (or nil if no)
+comment(# match\). Note that the object at the right of the operator needs)
+comment(# not to be a Regexp object (it can be a String\). The "dont)
+comment(# match" operator yields true or false.)
+ident(meadow) operator(=)operator(~) regexp<delimiter(/)content(sheep)delimiter(/)> comment(# position of the match, nil if no match)
+ident(meadow) operator(!)operator(~) regexp<delimiter(/)content(sheep)delimiter(/)> comment(# true if doesn't match, false if it does)
+comment(# There is no sugared version for the substitution)
+
+ident(meadow) operator(=)operator(~) regexp<delimiter(/)char(\\b)content(ovines?)char(\\b)delimiter(/)modifier(i)> reserved(and) ident(print) string<delimiter(")content(Here be sheep!)delimiter(")>
+
+ident(string) operator(=) string<delimiter(")content(good food)delimiter(")>
+ident(string)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(o*)delimiter(/)>operator(,) string<delimiter(')content(e)delimiter(')>operator(\))
+
+comment(# % echo ababacaca | ruby -ne 'puts $& if /(a|ba|b\)+(a|ac\)+/')
+comment(# ababa)
+
+comment(# The "global" (or "multiple"\) match is handled by String#scan)
+ident(scan) operator(()regexp<delimiter(/)content(()char(\\d)content(+\))delimiter(/)>operator(\)) operator({)
+ ident(puts) string<delimiter(")content(Found number )inline<delimiter(#{)global_variable($1)delimiter(})>delimiter(")>
+operator(})
+
+comment(# String#scan yields an Array if not used with a block)
+ident(numbers) operator(=) ident(scan)operator(()regexp<delimiter(/)char(\\d)content(+)delimiter(/)>operator(\))
+
+ident(digits) operator(=) string<delimiter(")content(123456789)delimiter(")>
+ident(nonlap) operator(=) ident(digits)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\d)char(\\d)char(\\d)content(\))delimiter(/)>operator(\))
+ident(yeslap) operator(=) ident(digits)operator(.)ident(scan)operator(()regexp<delimiter(/)content((?=()char(\\d)char(\\d)char(\\d)content(\)\))delimiter(/)>operator(\))
+ident(puts) string<delimiter(")content(Non-overlapping: )inline<delimiter(#{)ident(nonlap)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>delimiter(")>
+ident(puts) string<delimiter(")content(Overlapping: )inline<delimiter(#{)ident(yeslap)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>delimiter(")>operator(;)
+comment(# Non-overlapping: 123 456 789)
+comment(# Overlapping: 123 234 345 456 567 678 789)
+
+ident(string) operator(=) string<delimiter(")content(And little lambs eat ivy)delimiter(")>
+ident(string) operator(=)operator(~) regexp<delimiter(/)content(l[^s]*s)delimiter(/)>
+ident(puts) string<delimiter(")content(()escape(#)global_variable($`)content(\) ()escape(#)global_variable($&)content(\) ()escape(#)global_variable($')content(\))delimiter(")>
+comment(# (And \) (little lambs\) ( eat ivy\))
+
+
+comment(# @@PLEAC@@_6.1)
+comment(# Ruby doesn't have the same problem:)
+ident(dst) operator(=) ident(src)operator(.)ident(sub)operator(()string<delimiter(')content(this)delimiter(')>operator(,) string<delimiter(')content(that)delimiter(')>operator(\))
+
+ident(progname) operator(=) global_variable($0)operator(.)ident(sub)operator(()string<delimiter(')content(^.*/)delimiter(')>operator(,) string<delimiter(')delimiter(')>operator(\))
+
+ident(bindirs) operator(=) string<delimiter(%w()content(/usr/bin /bin /usr/local/bin)delimiter(\))>
+ident(libdirs) operator(=) ident(bindirs)operator(.)ident(map) operator({) operator(|)ident(l)operator(|) ident(l)operator(.)ident(sub)operator(()string<delimiter(')content(bin)delimiter(')>operator(,) string<delimiter(')content(lib)delimiter(')>operator(\)) operator(})
+
+
+comment(# @@PLEAC@@_6.3)
+regexp<delimiter(/)char(\\S)content(+)delimiter(/)> comment(# as many non-whitespace bytes as possible)
+regexp<delimiter(/)content([A-Za-z'-]+)delimiter(/)> comment(# as many letters, apostrophes, and hyphens)
+
+regexp<delimiter(/)char(\\b)content(([A-Za-z]+\))char(\\b)delimiter(/)> comment(# usually best)
+regexp<delimiter(/)char(\\s)content(([A-Za-z]+\))char(\\s)delimiter(/)> comment(# fails at ends or w/ punctuation)
+
+
+comment(# @@PLEAC@@_6.4)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+ident(str) operator(=) string<delimiter(')content(www.ruby-lang.org and www.rubygarden.org)delimiter(')>
+ident(re) operator(=) regexp<delimiter(/)content(
+ ( # capture the hostname in $1
+ (?: # these parens for grouping only
+ (?! [-_] \) # lookahead for neither underscore nor dash
+ [)char(\\w)content(-] + # hostname component
+ )char(\\.)content( # and the domain dot
+ \) + # now repeat that whole thing a bunch of times
+ [A-Za-z] # next must be a letter
+ [)char(\\w)content(-] + # now trailing domain part
+ \) # end of $1 capture
+ )delimiter(/)modifier(x)> comment(# /x for nice formatting)
+
+ident(str)operator(.)ident(gsub!) ident(re) reserved(do) comment(# pass a block to execute replacement)
+ ident(host) operator(=) constant(TCPsocket)operator(.)ident(gethostbyname)operator(()global_variable($1)operator(\))
+ string<delimiter(")inline<delimiter(#{)global_variable($1)delimiter(})>content( [)inline<delimiter(#{)ident(host)operator([)integer(3)operator(])delimiter(})>content(])delimiter(")>
+reserved(end)
+
+ident(puts) ident(str)
+comment(#-----------------------------)
+comment(# to match whitespace or #-characters in an extended re you need to escape)
+comment(# them.)
+
+ident(foo) operator(=) integer(42)
+ident(str) operator(=) string<delimiter(')content(blah #foo# blah)delimiter(')>
+ident(str)operator(.)ident(gsub!) regexp<delimiter(%r/)content( # replace
+ )char(\\#)content( # a pound sign
+ ()char(\\w)content(+\) # the variable name
+ )char(\\#)content( # another pound sign
+ )delimiter(/)modifier(x)> reserved(do)
+ ident(eval) global_variable($1) comment(# with the value of a local variable)
+ reserved(end)
+ident(puts) ident(str) comment(# => blah 42 blah)
+
+
+comment(# @@PLEAC@@_6.5)
+comment(# The 'g' modifier doesn't exist in Ruby, a regexp can't be used)
+comment(# directly in a while loop; instead, use String#scan { |match| .. } )
+ident(fish) operator(=) string<delimiter(')content(One fish two fish red fish blue fish)delimiter(')>
+constant(WANT) operator(=) integer(3)
+ident(count) operator(=) integer(0)
+ident(fish)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\w)content(+\))char(\\s)content(+fish)char(\\b)delimiter(/)modifier(i)>operator(\)) operator({)
+ reserved(if) operator(()ident(count) operator(+)operator(=) integer(1)operator(\)) operator(==) constant(WANT)
+ ident(puts) string<delimiter(")content(The third fish is a )inline<delimiter(#{)global_variable($1)delimiter(})>content( one.)delimiter(")>
+ reserved(end)
+operator(})
+
+reserved(if) ident(fish) operator(=)operator(~) regexp<delimiter(/)content((?:)char(\\w)content(+)char(\\s)content(+fish)char(\\s)content(+\){2}()char(\\w)content(+\))char(\\s)content(+fish)delimiter(/)modifier(i)>
+ ident(puts) string<delimiter(")content(The third fish is a )inline<delimiter(#{)global_variable($1)delimiter(})>content( one.)delimiter(")>
+reserved(end)
+
+ident(pond) operator(=) string<delimiter(')content(One fish two fish red fish blue fish)delimiter(')>
+comment(# String#scan without a block gives an array of matches, each match)
+comment(# being an array of all the specified groups)
+ident(colors) operator(=) ident(pond)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\w)content(+\))char(\\s)content(+fish)char(\\b)delimiter(/)modifier(i)>operator(\))operator(.)ident(flatten) comment(# get all matches)
+ident(color) operator(=) ident(colors)operator([)integer(2)operator(]) comment(# then the one we want)
+comment(# or without a temporary array)
+ident(color) operator(=) ident(pond)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\w)content(+\))char(\\s)content(+fish)char(\\b)delimiter(/)modifier(i)>operator(\))operator(.)ident(flatten)operator([)integer(2)operator(]) comment(# just grab element 3)
+ident(puts) string<delimiter(")content(The third fish in the pond is )inline<delimiter(#{)ident(color)delimiter(})>content(.)delimiter(")>
+
+ident(count) operator(=) integer(0)
+ident(fishes) operator(=) string<delimiter(')content(One fish two fish red fish blue fish)delimiter(')>
+ident(evens) operator(=) ident(fishes)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\w)content(+\))char(\\s)content(+fish)char(\\b)delimiter(/)modifier(i)>operator(\))operator(.)ident(select) operator({) operator(()ident(count)operator(+)operator(=)integer(1)operator(\)) operator(%) integer(2) operator(==) integer(0) operator(})
+ident(print) string<delimiter(")content(Even numbered fish are )inline<delimiter(#{)ident(evens)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>content(.)delimiter(")>
+
+ident(count) operator(=) integer(0)
+ident(fishes)operator(.)ident(gsub)operator(()regexp<delimiter(/)content(
+ )char(\\b)content( # makes next )char(\\w)content( more efficient
+ ( )char(\\w)content(+ \) # this is what we)char(\\')content(ll be changing
+ (
+ )char(\\s)content(+ fish )char(\\b)content(
+ \)
+ )delimiter(/)modifier(x)>operator(\)) operator({)
+ reserved(if) operator(()ident(count) operator(+)operator(=) integer(1)operator(\)) operator(==) integer(4)
+ string<delimiter(')content(sushi)delimiter(')> operator(+) global_variable($2)
+ reserved(else)
+ global_variable($1) operator(+) global_variable($2)
+ reserved(end)
+operator(})
+
+ident(pond) operator(=) string<delimiter(')content(One fish two fish red fish blue fish swim here.)delimiter(')>
+ident(puts) string<delimiter(")content(Last fish is )inline<delimiter(#{)ident(pond)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\b)content(()char(\\w)content(+\))char(\\s)content(+fish)char(\\b)delimiter(/)modifier(i)>operator(\))operator(.)ident(flatten)operator([)operator(-)integer(1)operator(])delimiter(})>delimiter(")>
+
+regexp<delimiter(/)content(
+ A # find some pattern A
+ (?! # mustn)char(\\')content(t be able to find
+ .* # something
+ A # and A
+ \)
+ $ # through the end of the string
+)delimiter(/)modifier(x)>
+
+comment(# The "s" perl modifier is "m" in Ruby (not very nice since there is)
+comment(# also an "m" in perl..\))
+ident(pond) operator(=) string<delimiter(")content(One fish two fish red fish blue fish swim here.)delimiter(")>
+reserved(if) operator(()ident(pond) operator(=)operator(~) regexp<delimiter(/)content(
+ )char(\\b)content( ( )char(\\w)content(+\) )char(\\s)content(+ fish )char(\\b)content(
+ (?! .* )char(\\b)content( fish )char(\\b)content( \)
+ )delimiter(/)modifier(mix)>operator(\))
+ ident(puts) string<delimiter(")content(Last fish is )inline<delimiter(#{)global_variable($1)delimiter(})>content(.)delimiter(")>
+reserved(else)
+ ident(puts) string<delimiter(")content(Failed!)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.6)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# killtags - very bad html killer)
+global_variable($/) operator(=) pre_constant(nil)operator(;) comment(# each read is whole file)
+reserved(while) ident(file) operator(=) ident(gets)operator(()operator(\)) reserved(do)
+ ident(file)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(<.*?>)delimiter(/)modifier(m)>operator(,)string<delimiter(')delimiter(')>operator(\))operator(;) comment(# strip tags (terribly\))
+ ident(puts) ident(file) comment(# print file to STDOUT)
+reserved(end)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(#headerfy - change certain chapter headers to html)
+global_variable($/) operator(=) string<delimiter(')delimiter(')>
+reserved(while) ident(file) operator(=) ident(gets)operator(()operator(\)) reserved(do)
+ ident(pattern) operator(=) regexp<delimiter(/)content(
+ )char(\\A)content( # start of record
+ ( # capture in $1
+ Chapter # text string
+ )char(\\s)content(+ # mandatory whitespace
+ )char(\\d)content(+ # decimal number
+ )char(\\s)content(* # optional whitespace
+ : # a real colon
+ . * # anything not a newline till end of line
+ \)
+ )delimiter(/)modifier(x)>
+ ident(puts) ident(file)operator(.)ident(gsub)operator(()ident(pattern)operator(,)string<delimiter(')content(<H1>)content(\\1)content(</H1>)delimiter(')>operator(\))
+reserved(end)
+comment(#-----------------------------)
+comment(#% ruby -00pe "gsub!(/\\A(Chapter\\s+\\d+\\s*:.*\)/,'<H1>\\1</H1>'\)" datafile)
+
+comment(#!/usr/bin/ruby -w)
+comment(#-----------------------------)
+reserved(for) ident(file) reserved(in) pre_constant(ARGV)
+ ident(file) operator(=) constant(File)operator(.)ident(open)operator(()pre_constant(ARGV)operator(.)ident(shift)operator(\))
+ reserved(while) ident(file)operator(.)ident(gets)operator(()string<delimiter(')delimiter(')>operator(\)) reserved(do) comment(# each read is a paragraph)
+ ident(print) string<delimiter(")content(chunk )inline<delimiter(#{)global_variable($.)delimiter(})>content( in $ARGV has <<)inline<delimiter(#{)global_variable($1)delimiter(})>content(>>)char(\\n)delimiter(")> reserved(while) regexp<delimiter(/)content(^START(.*?\)^END)delimiter(/)modifier(m)>
+ reserved(end) comment(# /m activates the multiline mode)
+reserved(end)
+comment(#-----------------------------)
+
+comment(# @@PLEAC@@_6.7)
+comment(#-----------------------------)
+global_variable($/) operator(=) pre_constant(nil)operator(;)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()string<delimiter(")content(datafile)delimiter(")>operator(\))
+ident(chunks) operator(=) ident(file)operator(.)ident(gets)operator(.)ident(split)operator(()regexp<delimiter(/)content(pattern)delimiter(/)>operator(\))
+comment(#-----------------------------)
+comment(# .Ch, .Se and .Ss divide chunks of STDIN)
+ident(chunks) operator(=) ident(gets)operator(()pre_constant(nil)operator(\))operator(.)ident(split)operator(()regexp<delimiter(/)content(^)char(\\.)content((Ch|Se|Ss\)$)delimiter(/)>operator(\))
+ident(print) string<delimiter(")content(I read )inline<delimiter(#{)ident(chunks)operator(.)ident(size)delimiter(})>content( chunks.)char(\\n)delimiter(")>
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_6.8)
+reserved(while) ident(gets)
+ reserved(if) operator(~)regexp<delimiter(/)content(BEGIN)delimiter(/)> operator(..) operator(~)regexp<delimiter(/)content(END)delimiter(/)>
+ comment(# line falls between BEGIN and END inclusive)
+ reserved(end)
+reserved(end)
+
+reserved(while) ident(gets)
+ reserved(if) operator(()global_variable($.) operator(==) ident(firstnum)operator(\)) operator(..) operator(()global_variable($.) operator(==) ident(lastnum)operator(\))
+ comment(# operate between firstnum and lastnum line number)
+ reserved(end)
+reserved(end)
+
+comment(# in ruby versions prior to 1.8, the above two conditional)
+comment(# expressions could be shortened to:)
+comment(# if /BEGIN/ .. /END/)
+comment(# and)
+comment(# if firstnum .. lastnum)
+comment(# but these now only work this way from the command line )
+
+comment(#-----------------------------)
+
+reserved(while) ident(gets)
+ reserved(if) operator(~)regexp<delimiter(/)content(BEGIN)delimiter(/)> operator(...) operator(~)regexp<delimiter(/)content(END)delimiter(/)>
+ comment(# line falls between BEGIN and END on different lines)
+ reserved(end)
+reserved(end)
+
+reserved(while) ident(gets)
+ reserved(if) operator(()global_variable($.) operator(==) ident(first)operator(\)) operator(...) operator(()global_variable($.) operator(==) ident(last)operator(\))
+ comment(# operate between first and last line number on different lines)
+ reserved(end)
+reserved(end)
+
+comment(#-----------------------------)
+comment(# command-line to print lines 15 through 17 inclusive (see below\))
+ident(ruby) operator(-)ident(ne) string<delimiter(')content(print if 15 .. 17)delimiter(')> ident(datafile)
+
+comment(# print out all <XMP> .. </XMP> displays from HTML doc)
+reserved(while) ident(gets)
+ ident(print) reserved(if) operator(~)regexp<delimiter(%r#)content(<XMP>)delimiter(#)modifier(i)> operator(..) operator(~)regexp<delimiter(%r#)content(</XMP>)delimiter(#)modifier(i)>operator(;)
+reserved(end)
+
+comment(# same, but as shell command)
+comment(# ruby -ne 'print if %r#<XMP>#i .. %r#</XMP>#i' document.html)
+comment(#-----------------------------)
+comment(# ruby -ne 'BEGIN { $top=3; $bottom=5 }; \\)
+comment(# print if $top .. $bottom' /etc/passwd # FAILS)
+comment(# ruby -ne 'BEGIN { $top=3; $bottom=5 }; \\)
+comment(# print if $. == $top .. $. == $bottom' /etc/passwd # works)
+comment(# ruby -ne 'print if 3 .. 5' /etc/passwd # also works)
+comment(#-----------------------------)
+ident(print) reserved(if) operator(~)regexp<delimiter(/)content(begin)delimiter(/)> operator(..) operator(~)regexp<delimiter(/)content(end)delimiter(/)>operator(;)
+ident(print) reserved(if) operator(~)regexp<delimiter(/)content(begin)delimiter(/)> operator(...) operator(~)regexp<delimiter(/)content(end)delimiter(/)>operator(;)
+comment(#-----------------------------)
+reserved(while) ident(gets)
+ global_variable($in_header) operator(=) global_variable($.) operator(==) integer(1) operator(..) operator(~)regexp<delimiter(/)content(^$)delimiter(/)> operator(?) pre_constant(true) operator(:) pre_constant(false)
+ global_variable($in_body) operator(=) operator(~)regexp<delimiter(/)content(^$)delimiter(/)> operator(..) pre_constant(ARGF)operator(.)ident(eof) operator(?) pre_constant(true) operator(:) pre_constant(false)
+reserved(end)
+comment(#-----------------------------)
+ident(seen) operator(=) operator({)operator(})
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ reserved(next) reserved(unless) ident(line) operator(=)operator(~) regexp<delimiter(/)content(^From:?)char(\\s)delimiter(/)modifier(i)> operator(..) ident(line) operator(=)operator(~) regexp<delimiter(/)content(^$)delimiter(/)>operator(;)
+ ident(line)operator(.)ident(scan)operator(()regexp<delimiter(%r/)content(([^<>(\),;)char(\\s)content(]+)char(\\@)content([^<>(\),;)char(\\s)content(]+\))delimiter(/)>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(addr)operator(|)
+ ident(puts) ident(addr) reserved(unless) ident(seen)operator([)ident(addr)operator(])
+ ident(seen)operator([)ident(addr)operator(]) operator(||)operator(=) integer(1)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.9)
+reserved(def) method(glob2pat)operator(()ident(globstr)operator(\))
+ ident(patmap) operator(=) operator({)
+ string<delimiter(')content(*)delimiter(')> operator(=)operator(>) string<delimiter(')content(.*)delimiter(')>operator(,)
+ string<delimiter(')content(?)delimiter(')> operator(=)operator(>) string<delimiter(')content(.)delimiter(')>operator(,)
+ string<delimiter(')content([)delimiter(')> operator(=)operator(>) string<delimiter(')content([)delimiter(')>operator(,)
+ string<delimiter(')content(])delimiter(')> operator(=)operator(>) string<delimiter(')content(])delimiter(')>operator(,)
+ operator(})
+ ident(globstr)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content((.\))delimiter(/)>operator(\)) operator({) operator(|)ident(c)operator(|) ident(patmap)operator([)ident(c)operator(]) operator(||) constant(Regexp)operator(::)ident(escape)operator(()ident(c)operator(\)) operator(})
+ string<delimiter(')content(^)delimiter(')> operator(+) ident(globstr) operator(+) string<delimiter(')content($)delimiter(')>
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.10)
+comment(# avoid interpolating patterns like this if the pattern)
+comment(# isn't going to change:)
+ident(pattern) operator(=) pre_constant(ARGV)operator(.)ident(shift)
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)inline<delimiter(#{)ident(pattern)delimiter(})>delimiter(/)>
+reserved(end)
+
+comment(# the above creates a new regex each iteration. Instead,)
+comment(# use the /o modifier so the regex is compiled only once)
+
+ident(pattern) operator(=) pre_constant(ARGV)operator(.)ident(shift)
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)inline<delimiter(#{)ident(pattern)delimiter(})>delimiter(/)modifier(o)>
+reserved(end)
+
+comment(#-----------------------------)
+
+comment(#!/usr/bin/ruby)
+comment(# popgrep1 - grep for abbreviations of places that say "pop")
+comment(# version 1: slow but obvious way)
+ident(popstates) operator(=) string<delimiter(%w()content(CO ON MI WI MN)delimiter(\))>
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(popstates)operator(.)ident(each) reserved(do) operator(|)ident(state)operator(|)
+ reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)char(\\b)inline<delimiter(#{)ident(state)delimiter(})>char(\\b)delimiter(/)>
+ ident(print) ident(line)
+ ident(last)
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby)
+comment(# popgrep2 - grep for abbreviations of places that say "pop")
+comment(# version 2: eval strings; fast but hard to quote)
+ident(popstates) operator(=) string<delimiter(%w()content(CO ON MI WI MN)delimiter(\))>
+ident(code) operator(=) string<delimiter(")content(ARGF.each do |line|)char(\\n)delimiter(")>
+ident(popstates)operator(.)ident(each) reserved(do) operator(|)ident(state)operator(|)
+ ident(code) operator(+)operator(=) string<delimiter(")char(\\t)content(if line =~ /)char(\\\\)content(b)inline<delimiter(#{)ident(state)delimiter(})>char(\\\\)content(b/; print(line\); next; end)char(\\n)delimiter(")>
+reserved(end)
+ident(code) operator(+)operator(=) string<delimiter(")content(end)char(\\n)delimiter(")>
+ident(print) string<delimiter(")content(CODE IS)char(\\n)content(---)char(\\n)inline<delimiter(#{)ident(code)delimiter(})>char(\\n)content(---)char(\\n)delimiter(")> reserved(if) pre_constant(false) comment(# turn on for debugging)
+ident(eval) ident(code)
+
+comment(# CODE IS)
+comment(# ---)
+comment(# ARGF.each do |line|)
+comment(# if line =~ /\\bCO\\b/; print(line\); next; end)
+comment(# if line =~ /\\bON\\b/; print(line\); next; end)
+comment(# if line =~ /\\bMI\\b/; print(line\); next; end)
+comment(# if line =~ /\\bWI\\b/; print(line\); next; end)
+comment(# if line =~ /\\bMN\\b/; print(line\); next; end)
+comment(# end)
+comment(# )
+comment(# ---)
+
+comment(## alternatively, the same idea as above but compiling )
+comment(## to a case statement: (not in perlcookbook\))
+comment(#!/usr/bin/ruby -w)
+comment(# popgrep2.5 - grep for abbreviations of places that say "pop")
+comment(# version 2.5: eval strings; fast but hard to quote)
+ident(popstates) operator(=) string<delimiter(%w()content(CO ON MI WI MN)delimiter(\))>
+ident(code) operator(=) string<delimiter(")content(ARGF.each do |line|)char(\\n)content( case line)char(\\n)delimiter(")>
+ident(popstates)operator(.)ident(each) reserved(do) operator(|)ident(state)operator(|)
+ ident(code) operator(+)operator(=) string<delimiter(")content( when /)char(\\\\)content(b)inline<delimiter(#{)ident(state)delimiter(})>char(\\\\)content(b/ : print line)char(\\n)delimiter(")>
+reserved(end)
+ident(code) operator(+)operator(=) string<delimiter(")content( end)char(\\n)content(end)char(\\n)delimiter(")>
+ident(print) string<delimiter(")content(CODE IS)char(\\n)content(---)char(\\n)inline<delimiter(#{)ident(code)delimiter(})>char(\\n)content(---)char(\\n)delimiter(")> reserved(if) pre_constant(false) comment(# turn on for debugging)
+ident(eval) ident(code)
+
+comment(# CODE IS)
+comment(# ---)
+comment(# ARGF.each do |line|)
+comment(# case line)
+comment(# when /\\bCO\\b/ : print line)
+comment(# when /\\bON\\b/ : print line)
+comment(# when /\\bMI\\b/ : print line)
+comment(# when /\\bWI\\b/ : print line)
+comment(# when /\\bMN\\b/ : print line)
+comment(# end)
+comment(# end)
+comment(# )
+comment(# ---)
+
+comment(# Note: (above\) Ruby 1.8+ allows the 'when EXP : EXPR' on one line)
+comment(# with the colon separator.)
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby)
+comment(# popgrep3 - grep for abbreviations of places that say "pop")
+comment(# version3: build a match_any function)
+ident(popstates) operator(=) string<delimiter(%w()content(CO ON MI WI MN)delimiter(\))>
+ident(expr) operator(=) ident(popstates)operator(.)ident(map)operator({)operator(|)ident(e)operator(|)string<delimiter(")content(line =~ /)char(\\\\)content(b)inline<delimiter(#{)ident(e)delimiter(})>char(\\\\)content(b/)delimiter(")>operator(})operator(.)ident(join)operator(()string<delimiter(')content(||)delimiter(')>operator(\))
+ident(eval) string<delimiter(")content(def match_any(line\); )inline<delimiter(#{)ident(expr)delimiter(})>content(;end)delimiter(")>
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(match_any)operator(()ident(line)operator(\))
+reserved(end)
+comment(#-----------------------------)
+
+comment(## building a match_all function is a trivial)
+comment(## substitution of && for ||)
+comment(## here is a generalized example:)
+comment(#!/usr/bin/ruby -w)
+comment(## grepauth - print lines that mention both foo and bar)
+reserved(class) class(MultiMatch)
+ reserved(def) method(initialize)operator(()operator(*)ident(patterns)operator(\))
+ ident(_any) operator(=) ident(build_match)operator(()string<delimiter(')content(||)delimiter(')>operator(,)ident(patterns)operator(\))
+ ident(_all) operator(=) ident(build_match)operator(()string<delimiter(')content(&&)delimiter(')>operator(,)ident(patterns)operator(\))
+ ident(eval) string<delimiter(")content(def match_any(line\);)inline<delimiter(#{)ident(_any)delimiter(})>content(;end)char(\\n)delimiter(")>
+ ident(eval) string<delimiter(")content(def match_all(line\);)inline<delimiter(#{)ident(_all)delimiter(})>content(;end)char(\\n)delimiter(")>
+ reserved(end)
+ reserved(def) method(build_match)operator(()ident(sym)operator(,)ident(args)operator(\))
+ ident(args)operator(.)ident(map)operator({)operator(|)ident(e)operator(|)string<delimiter(")content(line =~ /)inline<delimiter(#{)ident(e)delimiter(})>content(/)delimiter(")>operator(})operator(.)ident(join)operator(()ident(sym)operator(\))
+ reserved(end)
+reserved(end)
+
+ident(mm) operator(=) constant(MultiMatch)operator(.)ident(new)operator(()string<delimiter(')content(foo)delimiter(')>operator(,)string<delimiter(')content(bar)delimiter(')>operator(\))
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(mm)operator(.)ident(match_all)operator(()ident(line)operator(\))
+reserved(end)
+comment(#-----------------------------)
+
+comment(#!/usr/bin/ruby)
+comment(# popgrep4 - grep for abbreviations of places that say "pop")
+comment(# version4: pretty fast, but simple: compile all re's first:)
+ident(popstates) operator(=) string<delimiter(%w()content(CO ON MI WI MN)delimiter(\))>
+ident(popstates) operator(=) ident(popstates)operator(.)ident(map)operator({)operator(|)ident(re)operator(|) regexp<delimiter(%r/)char(\\b)inline<delimiter(#{)ident(re)delimiter(})>char(\\b)delimiter(/)>operator(})
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(popstates)operator(.)ident(each) reserved(do) operator(|)ident(state_re)operator(|)
+ reserved(if) ident(line) operator(=)operator(~) ident(state_re)
+ ident(print) ident(line)
+ reserved(break)
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+comment(## speeds trials on the jargon file(412\): 26006 lines, 1.3MB)
+comment(## popgrep1 => 7.040s)
+comment(## popgrep2 => 0.656s)
+comment(## popgrep2.5 => 0.633s)
+comment(## popgrep3 => 0.675s)
+comment(## popgrep4 => 1.027s)
+
+comment(# unless speed is criticial, the technique in popgrep4 is a)
+comment(# reasonable balance between speed and logical simplicity.)
+
+
+comment(# @@PLEAC@@_6.11)
+reserved(begin)
+ ident(print) string<delimiter(")content(Pattern? )delimiter(")>
+ ident(pat) operator(=) global_variable($stdin)operator(.)ident(gets)operator(.)ident(chomp)
+ constant(Regexp)operator(.)ident(new)operator(()ident(pat)operator(\))
+reserved(rescue)
+ ident(warn) string<delimiter(")content(Invalid Pattern)delimiter(")>
+ reserved(retry)
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.13)
+comment(# uses the 'amatch' extension found on:)
+comment(# http://raa.ruby-lang.org/project/amatch/)
+ident(require) string<delimiter(')content(amatch)delimiter(')>
+ident(matcher) operator(=) constant(Amatch)operator(.)ident(new)operator(()string<delimiter(')content(balast)delimiter(')>operator(\))
+comment(#$relative, $distance = 0, 1)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(/usr/share/dict/words)delimiter(')>operator(\))operator(.)ident(each_line) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(matcher)operator(.)ident(search)operator(()ident(line)operator(\)) operator(<=) integer(1)
+reserved(end)
+comment(__END__
+)comment(#CODE)
+ident(ballast)
+ident(ballasts)
+ident(balustrade)
+ident(balustrades)
+ident(blast)
+ident(blasted)
+ident(blaster)
+ident(blasters)
+ident(blasting)
+ident(blasts)
+
+
+comment(# @@PLEAC@@_6.14)
+ident(str)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\G)content(()char(\\d)content(\))delimiter(/)>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(token)operator(|)
+ ident(puts) string<delimiter(")content(found )inline<delimiter(#{)ident(token)delimiter(})>delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+ident(n) operator(=) string<delimiter(")content( 49 here)delimiter(")>
+ident(n)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\G)content( )delimiter(/)>operator(,)string<delimiter(')content(0)delimiter(')>operator(\))
+ident(puts) ident(n)
+comment(#-----------------------------)
+ident(str) operator(=) string<delimiter(")content(3,4,5,9,120)delimiter(")>
+ident(str)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\G)content(,?()char(\\d)content(+\))delimiter(/)>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(num)operator(|)
+ ident(puts) string<delimiter(")content(Found number: )inline<delimiter(#{)ident(num)delimiter(})>delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+comment(# Ruby doesn't have the String.pos or a /c re modifier like Perl )
+comment(# But it does have StringScanner in the standard library (strscn\))
+comment(# which allows similar functionality:)
+
+ident(require) string<delimiter(')content(strscan)delimiter(')>
+ident(text) operator(=) string<delimiter(')content(the year 1752 lost 10 days on the 3rd of September)delimiter(')>
+ident(sc) operator(=) constant(StringScanner)operator(.)ident(new)operator(()ident(text)operator(\))
+reserved(while) ident(sc)operator(.)ident(scan)operator(()regexp<delimiter(/)content(.*?()char(\\d)content(+\))delimiter(/)>operator(\))
+ ident(print) string<delimiter(")content(found: )inline<delimiter(#{)ident(sc)operator([)integer(1)operator(])delimiter(})>char(\\n)delimiter(")>
+reserved(end)
+reserved(if) ident(sc)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\S)content(+)delimiter(/)>operator(\))
+ ident(puts) string<delimiter(")content(Found )inline<delimiter(#{)ident(sc)operator([)integer(0)operator(])delimiter(})>content( after last number)delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+comment(# assuming continuing from above:)
+ident(puts) string<delimiter(")content(The position in 'text' is: )inline<delimiter(#{)ident(sc)operator(.)ident(pos)delimiter(})>delimiter(")>
+ident(sc)operator(.)ident(pos) operator(=) integer(30)
+ident(puts) string<delimiter(")content(The position in 'text' is: )inline<delimiter(#{)ident(sc)operator(.)ident(pos)delimiter(})>delimiter(")>
+
+
+comment(# @@PLEAC@@_6.15)
+comment(#-----------------------------)
+comment(# greedy pattern)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(<.*>)delimiter(/)modifier(m)>operator(,)string<delimiter(')delimiter(')>operator(\)) comment(# not good)
+
+comment(# non-greedy (minimal\) pattern)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(<.*?>)delimiter(/)modifier(m)>operator(,)string<delimiter(')delimiter(')>operator(\)) comment(# not great)
+
+
+comment(#-----------------------------)
+comment(#<b><i>this</i> and <i>that</i> are important</b> Oh, <b><i>me too!</i></b>)
+comment(#-----------------------------)
+regexp<delimiter(%r{)content( <b><i>(.*?\)</i></b> )delimiter(})modifier(mx)>
+comment(#-----------------------------)
+regexp<delimiter(%r/)content(BEGIN((?:(?!BEGIN\).\)*\)END)delimiter(/)>
+comment(#-----------------------------)
+regexp<delimiter(%r{)content( <b><i>( (?: (?!</b>|</i>\). \)* \) </i></b> )delimiter(})modifier(mx)>
+comment(#-----------------------------)
+regexp<delimiter(%r{)content( <b><i>( (?: (?!</[ib]>\). \)* \) </i></b> )delimiter(})modifier(mx)>
+comment(#-----------------------------)
+regexp<delimiter(%r{)content(
+ <b><i>
+ [^<]* # stuff not possibly bad, and not possibly the end.
+ (?:
+ # at this point, we can have '<' if not part of something bad
+ (?! </?[ib]> \) # what we can't have
+ < # okay, so match the '<'
+ [^<]* # and continue with more safe stuff
+ \) *
+ </i></b>
+ )delimiter(})modifier(mx)>
+
+
+comment(# @@PLEAC@@_6.16)
+comment(#-----------------------------)
+global_variable($/) operator(=) string<delimiter(")delimiter(")>
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(para)operator(|)
+ ident(para)operator(.)ident(scan) regexp<delimiter(%r/)content(
+ )char(\\b)content( # start at word boundary
+ ()char(\\S)content(+\) # find chunk of non-whitespace
+ )char(\\b)content( # until a word boundary
+ (
+ )char(\\s)content(+ # followed by whitespace
+ )char(\\1)content( # and that same chunk again
+ )char(\\b)content( # and a word boundary
+ \) + # one or more times
+ )delimiter(/)modifier(xi)> reserved(do)
+ ident(puts) string<delimiter(")content(dup word ')inline<delimiter(#{)global_variable($1)delimiter(})>content(' at paragraph )inline<delimiter(#{)global_variable($.)delimiter(})>delimiter(")>
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+ident(astr) operator(=) string<delimiter(')content(nobody)delimiter(')>
+ident(bstr) operator(=) string<delimiter(')content(bodysnatcher)delimiter(')>
+reserved(if) string<delimiter(")inline<delimiter(#{)ident(astr)delimiter(})>content( )inline<delimiter(#{)ident(bstr)delimiter(})>delimiter(")> operator(=)operator(~) regexp<delimiter(/)content(^()char(\\w)content(+\)()char(\\w)content(+\) )char(\\2)content(()char(\\w)content(+\)$)delimiter(/)>
+ ident(print) string<delimiter(")inline<delimiter(#{)global_variable($2)delimiter(})>content( overlaps in )inline<delimiter(#{)global_variable($1)delimiter(})>content(-)inline<delimiter(#{)global_variable($2)delimiter(})>content(-)inline<delimiter(#{)global_variable($3)delimiter(})>delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# prime_pattern -- find prime factors of argument using patterns)
+pre_constant(ARGV) operator(<<) integer(180)
+ident(cap) operator(=) string<delimiter(')content(o)delimiter(')> operator(*) pre_constant(ARGV)operator(.)ident(shift)
+reserved(while) ident(cap) operator(=)operator(~) regexp<delimiter(/)content(^(oo+?\))char(\\1)content(+$)delimiter(/)>
+ ident(print) global_variable($1)operator(.)ident(size)operator(,) string<delimiter(")content( )delimiter(")>
+ ident(cap)operator(.)ident(gsub!)operator(()regexp<delimiter(/)inline<delimiter(#{)global_variable($1)delimiter(})>delimiter(/)>operator(,)string<delimiter(')content(o)delimiter(')>operator(\))
+reserved(end)
+ident(puts) ident(cap)operator(.)ident(size)
+comment(#-----------------------------)
+comment(#diophantine)
+comment(# solve for 12x + 15y + 16z = 281, maximizing x)
+reserved(if) operator(()string<delimiter(')content(o)delimiter(')> operator(*) integer(281)operator(\))operator(.)ident(match)operator(()regexp<delimiter(/)content(^(o*\))char(\\1)content({11}(o*\))char(\\2)content({14}(o*\))char(\\3)content({15}$)delimiter(/)>operator(\))
+ ident(x)operator(,) ident(y)operator(,) ident(z) operator(=) global_variable($1)operator(.)ident(size)operator(,) global_variable($2)operator(.)ident(size)operator(,) global_variable($3)operator(.)ident(size)
+ ident(puts) string<delimiter(")content(One solution is: x=)inline<delimiter(#{)ident(x)delimiter(})>content(; y=)inline<delimiter(#{)ident(y)delimiter(})>content(; z=)inline<delimiter(#{)ident(z)delimiter(})>delimiter(")>
+reserved(else)
+ ident(puts) string<delimiter(")content(No solution.)delimiter(")>
+reserved(end)
+comment(# => One solution is: x=17; y=3; z=2)
+
+comment(#-----------------------------)
+comment(# using different quantifiers:)
+operator(()string<delimiter(')content(o)delimiter(')> operator(*) integer(281)operator(\))operator(.)ident(match)operator(()regexp<delimiter(/)content(^(o+\))char(\\1)content({11}(o+\))char(\\2)content({14}(o+\))char(\\3)content({15}$)delimiter(/)>operator(\))
+comment(# => One solution is: x=17; y=3; z=2)
+
+operator(()string<delimiter(')content(o)delimiter(')> operator(*) integer(281)operator(\))operator(.)ident(match)operator(()regexp<delimiter(/)content(^(o*?\))char(\\1)content({11}(o*\))char(\\2)content({14}(o*\))char(\\3)content({15}$)delimiter(/)>operator(\))
+comment(# => One solution is: x=0; y=7; z=11)
+
+operator(()string<delimiter(')content(o)delimiter(')> operator(*) integer(281)operator(\))operator(.)ident(match)operator(()regexp<delimiter(/)content(^(o+?\))char(\\1)content({11}(o*\))char(\\2)content({14}(o*\))char(\\3)content({15}$)delimiter(/)>operator(\))
+comment(# => One solution is: x=1; y=3; z=14)
+
+
+comment(# @@PLEAC@@_6.17)
+comment(# alpha OR beta)
+regexp<delimiter(%r/)content(alpha|beta)delimiter(/)>
+
+comment(# alpha AND beta)
+regexp<delimiter(%r/)content((?=.*alpha\)(?=.*beta\))delimiter(/)modifier(m)>
+
+comment(# alpha AND beta, no overlap)
+regexp<delimiter(%r/)content(alpha.*beta|beta.*alpha)delimiter(/)modifier(m)>
+
+comment(# NOT beta)
+regexp<delimiter(%r/)content(^(?:(?!beta\).\)*$)delimiter(/)modifier(m)>
+
+comment(# NOT bad BUT good)
+regexp<delimiter(%r/)content((?=(?:(?!BAD\).\)*$\)GOOD)delimiter(/)modifier(m)>
+comment(#-----------------------------)
+
+reserved(if) operator(!)operator(()ident(string) operator(=)operator(~) regexp<delimiter(/)content(pattern)delimiter(/)>operator(\)) comment(# ugly)
+ ident(something)operator(()operator(\))
+reserved(end)
+
+reserved(if) ident(string) operator(!)operator(~) regexp<delimiter(/)content(pattern)delimiter(/)> comment(# preferred)
+ ident(something)operator(()operator(\))
+reserved(end)
+
+
+comment(#-----------------------------)
+reserved(if) ident(string) operator(=)operator(~) regexp<delimiter(/)content(pat1)delimiter(/)> operator(&&) ident(string) operator(=)operator(~) regexp<delimiter(/)content(pat2)delimiter(/)>
+ ident(something)operator(()operator(\))
+reserved(end)
+comment(#-----------------------------)
+reserved(if) ident(string) operator(=)operator(~) regexp<delimiter(/)content(pat1)delimiter(/)> operator(||) ident(string) operator(=)operator(~) regexp<delimiter(/)content(pat2)delimiter(/)>
+ ident(something)operator(()operator(\))
+reserved(end)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# minigrep - trivial grep)
+ident(pat) operator(=) pre_constant(ARGV)operator(.)ident(shift)
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(print) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)inline<delimiter(#{)ident(pat)delimiter(})>delimiter(/)modifier(o)>
+reserved(end)
+comment(#-----------------------------)
+ string<delimiter(")content(labelled)delimiter(")> operator(=)operator(~) regexp<delimiter(/)content(^(?=.*bell\)(?=.*lab\))delimiter(/)modifier(m)>
+comment(#-----------------------------)
+global_variable($string) operator(=)operator(~) regexp<delimiter(/)content(bell)delimiter(/)> operator(&&) global_variable($string) operator(=)operator(~) regexp<delimiter(/)content(lab)delimiter(/)>
+comment(#-----------------------------)
+global_variable($murray_hill) operator(=) string<delimiter(")content(blah bell blah )delimiter(")>
+reserved(if) global_variable($murray_hill) operator(=)operator(~) regexp<delimiter(%r{)content(
+ ^ # start of string
+ (?= # zero-width lookahead
+ .* # any amount of intervening stuff
+ bell # the desired bell string
+ \) # rewind, since we were only looking
+ (?= # and do the same thing
+ .* # any amount of intervening stuff
+ lab # and the lab part
+ \)
+ )delimiter(})modifier(mx)> comment(# /m means . can match newline)
+
+ ident(print) string<delimiter(")content(Looks like Bell Labs might be in Murray Hill!)char(\\n)delimiter(")>operator(;)
+reserved(end)
+comment(#-----------------------------)
+string<delimiter(")content(labelled)delimiter(")> operator(=)operator(~) regexp<delimiter(/)content((?:^.*bell.*lab\)|(?:^.*lab.*bell\))delimiter(/)>
+comment(#-----------------------------)
+global_variable($brand) operator(=) string<delimiter(")content(labelled)delimiter(")>operator(;)
+reserved(if) global_variable($brand) operator(=)operator(~) regexp<delimiter(%r{)content(
+ (?: # non-capturing grouper
+ ^ .*? # any amount of stuff at the front
+ bell # look for a bell
+ .*? # followed by any amount of anything
+ lab # look for a lab
+ \) # end grouper
+ | # otherwise, try the other direction
+ (?: # non-capturing grouper
+ ^ .*? # any amount of stuff at the front
+ lab # look for a lab
+ .*? # followed by any amount of anything
+ bell # followed by a bell
+ \) # end grouper
+ )delimiter(})modifier(mx)> comment(# /m means . can match newline)
+ ident(print) string<delimiter(")content(Our brand has bell and lab separate.)char(\\n)delimiter(")>operator(;)
+reserved(end)
+comment(#-----------------------------)
+global_variable($map) operator(=)operator(~) regexp<delimiter(/)content(^(?:(?!waldo\).\)*$)delimiter(/)modifier(s)>
+comment(#-----------------------------)
+global_variable($map) operator(=) string<delimiter(")content(the great baldo)delimiter(")>
+reserved(if) global_variable($map) operator(=)operator(~) regexp<delimiter(%r{)content(
+ ^ # start of string
+ (?: # non-capturing grouper
+ (?! # look ahead negation
+ waldo # is he ahead of us now?
+ \) # is so, the negation failed
+ . # any character (cuzza /s\)
+ \) * # repeat that grouping 0 or more
+ $ # through the end of the string
+ )delimiter(})modifier(mx)> comment(# /m means . can match newline)
+ ident(print) string<delimiter(")content(There's no waldo here!)char(\\n)delimiter(")>operator(;)
+reserved(end)
+comment(=begin
+ 7:15am up 206 days, 13:30, 4 users, load average: 1.04, 1.07, 1.04
+
+USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
+
+tchrist tty1 5:16pm 36days 24:43 0.03s xinit
+
+tchrist tty2 5:19pm 6days 0.43s 0.43s -tcsh
+
+tchrist ttyp0 chthon 7:58am 3days 23.44s 0.44s -tcsh
+
+gnat ttyS4 coprolith 2:01pm 13:36m 0.30s 0.30s -tcsh
+=end)
+comment(#% w | minigrep '^(?!.*ttyp\).*tchrist')
+comment(#-----------------------------)
+regexp<delimiter(%r{)content(
+ ^ # anchored to the start
+ (?! # zero-width look-ahead assertion
+ .* # any amount of anything (faster than .*?\)
+ ttyp # the string you don't want to find
+ \) # end look-ahead negation; rewind to start
+ .* # any amount of anything (faster than .*?\)
+ tchrist # now try to find Tom
+)delimiter(})modifier(x)>
+comment(#-----------------------------)
+comment(#% w | grep tchrist | grep -v ttyp)
+comment(#-----------------------------)
+comment(#% grep -i 'pattern' files)
+comment(#% minigrep '(?i\)pattern' files)
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_6.20)
+ident(ans) operator(=) global_variable($stdin)operator(.)ident(gets)operator(.)ident(chomp)
+ident(re) operator(=) regexp<delimiter(%r/)content(^)inline<delimiter(#{)constant(Regexp)operator(.)ident(quote)operator(()ident(ans)operator(\))delimiter(})>delimiter(/)>
+reserved(case)
+ reserved(when) string<delimiter(")content(SEND)delimiter(")> operator(=)operator(~) ident(re) operator(:) ident(puts) string<delimiter(")content(Action is send)delimiter(")>
+ reserved(when) string<delimiter(")content(STOP)delimiter(")> operator(=)operator(~) ident(re) operator(:) ident(puts) string<delimiter(")content(Action is stop)delimiter(")>
+ reserved(when) string<delimiter(")content(ABORT)delimiter(")> operator(=)operator(~) ident(re) operator(:) ident(puts) string<delimiter(")content(Action is abort)delimiter(")>
+ reserved(when) string<delimiter(")content(EDIT)delimiter(")> operator(=)operator(~) ident(re) operator(:) ident(puts) string<delimiter(")content(Action is edit)delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+ident(require) string<delimiter(')content(abbrev)delimiter(')>
+ident(table) operator(=) constant(Abbrev)operator(.)ident(abbrev) string<delimiter(%w-)content(send stop abort edit)delimiter(-)>
+ident(loop) reserved(do)
+ ident(print) string<delimiter(")content(Action: )delimiter(")>
+ ident(ans) operator(=) global_variable($stdin)operator(.)ident(gets)operator(.)ident(chomp)
+ ident(puts) string<delimiter(")content(Action for )inline<delimiter(#{)ident(ans)delimiter(})>content( is )inline<delimiter(#{)ident(table)operator([)ident(ans)operator(.)ident(downcase)operator(])delimiter(})>delimiter(")>
+reserved(end)
+
+
+comment(#-----------------------------)
+comment(# dummy values are defined for 'file', 'PAGER', and)
+comment(# the 'invoke_editor' and 'deliver_message' methods)
+comment(# do not do anything interesting in this example.)
+comment(#!/usr/bin/ruby -w)
+ident(require) string<delimiter(')content(abbrev)delimiter(')>
+
+ident(file) operator(=) string<delimiter(')content(pleac_ruby.data)delimiter(')>
+constant(PAGER) operator(=) string<delimiter(')content(less)delimiter(')>
+
+reserved(def) method(invoke_editor)
+ ident(puts) string<delimiter(")content(invoking editor)delimiter(")>
+reserved(end)
+
+reserved(def) method(deliver_message)
+ ident(puts) string<delimiter(")content(delivering message)delimiter(")>
+reserved(end)
+
+ident(actions) operator(=) operator({)
+ string<delimiter(')content(edit)delimiter(')> operator(=)operator(>) pre_constant(self)operator(.)ident(method)operator(()symbol(:invoke_editor)operator(\))operator(,)
+ string<delimiter(')content(send)delimiter(')> operator(=)operator(>) pre_constant(self)operator(.)ident(method)operator(()symbol(:deliver_message)operator(\))operator(,)
+ string<delimiter(')content(list)delimiter(')> operator(=)operator(>) ident(proc) operator({)ident(system)operator(()constant(PAGER)operator(,) ident(file)operator(\))operator(})operator(,)
+ string<delimiter(')content(abort)delimiter(')> operator(=)operator(>) ident(proc) operator({)ident(puts) string<delimiter(")content(See ya!)delimiter(")>operator(;) ident(exit)operator(})operator(,)
+ string<delimiter(")delimiter(")> operator(=)operator(>) ident(proc) operator({)ident(puts) string<delimiter(")content(Unknown Command)delimiter(")>operator(})
+operator(})
+
+ident(dtable) operator(=) constant(Abbrev)operator(.)ident(abbrev)operator(()ident(actions)operator(.)ident(keys)operator(\))
+ident(loop) reserved(do)
+ ident(print) string<delimiter(")content(Action: )delimiter(")>
+ ident(ans) operator(=) global_variable($stdin)operator(.)ident(gets)operator(.)ident(chomp)operator(.)ident(delete)operator(()string<delimiter(")content( )char(\\t)delimiter(")>operator(\))
+ ident(actions)operator([) ident(dtable)operator([)ident(ans)operator(.)ident(downcase)operator(]) operator(||) string<delimiter(")delimiter(")> operator(])operator(.)ident(call)
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.19)
+comment(#-----------------------------)
+comment(# basically, the Perl Cookbook categorizes this as an)
+comment(# unsolvable problem ...)
+comment(#-----------------------------)
+integer(1) reserved(while) ident(addr)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\()content([^(\)]*)char(\\\))delimiter(/)>operator(,)string<delimiter(')delimiter(')>operator(\))
+comment(#-----------------------------)
+constant(Dear) ident(someuser)instance_variable(@host)operator(.)ident(com)operator(,)
+
+constant(Please) ident(confirm) ident(the) ident(mail) ident(address) ident(you) ident(gave) ident(us) constant(Wed) constant(May) integer(6) integer(09)operator(:)integer(38)operator(:)integer(41)
+constant(MDT) integer(1998) ident(by) ident(replying) ident(to) ident(this) ident(message)operator(.) constant(Include) ident(the) ident(string)
+string<delimiter(")content(Rumpelstiltskin)delimiter(")> reserved(in) ident(that) ident(reply)operator(,) ident(but) ident(spelled) reserved(in) ident(reverse)operator(;) ident(that) ident(is)operator(,)
+ident(start) ident(with) string<delimiter(")content(Nik...)delimiter(")>operator(.) constant(Once) ident(this) ident(is) ident(done)operator(,) ident(your) ident(confirmed) ident(address) ident(will)
+ident(be) ident(entered) ident(into) ident(our) ident(records)operator(.)
+
+
+comment(# @@PLEAC@@_6.21)
+comment(#-----------------------------)
+comment(#% gunzip -c ~/mail/archive.gz | urlify > archive.urlified)
+comment(#-----------------------------)
+comment(#% urlify ~/mail/*.inbox > ~/allmail.urlified)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# urlify - wrap HTML links around URL-like constructs)
+
+ident(urls) operator(=) string<delimiter(')content((https?|telnet|gopher|file|wais|ftp\))delimiter(')>operator(;)
+ident(ltrs) operator(=) string<delimiter(')content(\\w)delimiter(')>operator(;)
+ident(gunk) operator(=) string<delimiter(')content(/#~:.?+=&%@!)content(\\-)delimiter(')>operator(;)
+ident(punc) operator(=) string<delimiter(')content(.:?)content(\\-)delimiter(')>operator(;)
+ident(any) operator(=) string<delimiter(")inline<delimiter(#{)ident(ltrs)delimiter(})>inline<delimiter(#{)ident(gunk)delimiter(})>inline<delimiter(#{)ident(punc)delimiter(})>delimiter(")>operator(;)
+
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(line)operator(.)ident(gsub!) regexp<delimiter(%r/)content(
+ )char(\\b)content( # start at word boundary
+ ( # begin $1 {
+ )inline<delimiter(#{)ident(urls)delimiter(})>content( : # need resource and a colon
+ [)inline<delimiter(#{)ident(any)delimiter(})>content(] +? # followed by on or more
+ # of any valid character, but
+ # be conservative and take only
+ # what you need to....
+ \) # end $1 }
+ (?= # look-ahead non-consumptive assertion
+ [)inline<delimiter(#{)ident(punc)delimiter(})>content(]* # either 0 or more punctuation
+ [^)inline<delimiter(#{)ident(any)delimiter(})>content(] # followed by a non-url char
+ | # or else
+ $ # then end of the string
+ \)
+ )delimiter(/)modifier(iox)> reserved(do)
+ string<delimiter(%Q|)content(<A HREF=")inline<delimiter(#{)global_variable($1)delimiter(})>content(">)inline<delimiter(#{)global_variable($1)delimiter(})>content(</A>)delimiter(|)>
+ reserved(end)
+ ident(print) ident(line)
+reserved(end)
+
+
+comment(# @@PLEAC@@_6.23)
+regexp<delimiter(%r/)content(^m*(d?c{0,3}|c[dm]\)(l?x{0,3}|x[lc]\)(v?i{0,3}|i[vx]\)$)delimiter(/)modifier(i)>
+comment(#-----------------------------)
+ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(()char(\\S)content(+\)()char(\\s)content(+\)()char(\\S)content(+\))delimiter(/)>operator(,) string<delimiter(')content(\\3)content(\\2)content(\\1)delimiter(')>operator(\))
+comment(#-----------------------------)
+regexp<delimiter(%r/)content(()char(\\w)content(+\))char(\\s)content(*=)char(\\s)content(*(.*\))char(\\s)content(*$)delimiter(/)> comment(# keyword is $1, value is $2)
+comment(#-----------------------------)
+regexp<delimiter(%r/)content(.{80,})delimiter(/)>
+comment(#-----------------------------)
+regexp<delimiter(%r|)content(()char(\\d)content(+\)/()char(\\d)content(+\)/()char(\\d)content(+\) ()char(\\d)content(+\):()char(\\d)content(+\):()char(\\d)content(+\))delimiter(|)>
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(%r|)content(/usr/bin)delimiter(|)>operator(,)string<delimiter(')content(/usr/local/bin)delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(%([0-9A-Fa-f][0-9A-Fa-f]\))delimiter(/)>operator(\))operator({) global_variable($1)operator(.)ident(hex)operator(.)ident(chr) operator(})
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(%r{)content(
+ /)char(\\*)content( # Match the opening delimiter
+ .*? # Match a minimal number of characters
+ )char(\\*)content(/ # Match the closing delimiter
+)delimiter(})modifier(xm)>operator(,)string<delimiter(')delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(^)char(\\s)content(+)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)char(\\s)content(+$)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))
+
+comment(# but really, in Ruby we'd just do:)
+ident(str)operator(.)ident(strip!)
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\\\)content(n)delimiter(/)>operator(,)string<delimiter(")char(\\n)delimiter(")>operator(\))
+comment(#-----------------------------)
+ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(^.*::)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))
+comment(#-----------------------------)
+regexp<delimiter(%r/)content(^([01]?)char(\\d)char(\\d)content(|2[0-4])char(\\d)content(|25[0-5]\))char(\\.)content(([01]?)char(\\d)char(\\d)content(|2[0-4])char(\\d)content(|25[0-5]\))char(\\.)content(
+ ([01]?)char(\\d)char(\\d)content(|2[0-4])char(\\d)content(|25[0-5]\))char(\\.)content(([01]?)char(\\d)char(\\d)content(|2[0-4])char(\\d)content(|25[0-5]\)$)delimiter(/)modifier(x)>
+comment(#-----------------------------)
+ident(str)operator(.)ident(sub!)operator(()regexp<delimiter(%r|)content(^.*/)delimiter(|)>operator(,) string<delimiter(')delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(cols) operator(=) operator(() operator(()constant(ENV)operator([)string<delimiter(')content(TERMCAP)delimiter(')>operator(]) operator(||) string<delimiter(")content( )delimiter(")>operator(\)) operator(=)operator(~) regexp<delimiter(/)content(:co#()char(\\d)content(+\):)delimiter(/)> operator(\)) operator(?) global_variable($1) operator(:) integer(80)operator(;)
+comment(#-----------------------------)
+ident(name) operator(=) string<delimiter(")content( )inline<delimiter(#{)global_variable($0)delimiter(})>content( )inline<delimiter(#{)pre_constant(ARGV)delimiter(})>delimiter(")>operator(.)ident(gsub)operator(()regexp<delimiter(%r|)content( /)char(\\S)content(+/)delimiter(|)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(require) string<delimiter(')content(rbconfig)delimiter(')>
+ident(include) constant(Config)
+ident(raise) string<delimiter(")content(This isn't Linux)delimiter(")> reserved(unless) constant(CONFIG)operator([)string<delimiter(')content(target_os)delimiter(')>operator(]) operator(=)operator(~) regexp<delimiter(/)content(linux)delimiter(/)modifier(i)>operator(;)
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(%r/)char(\\n)char(\\s)content(+)delimiter(/)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(nums) operator(=) ident(str)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\d)content(+)char(\\.)content(?)char(\\d)content(*|)char(\\.)char(\\d)content(+\))delimiter(/)>operator(\))
+comment(#-----------------------------)
+ident(capwords) operator(=) ident(str)operator(.)ident(scan)operator(()regexp<delimiter(%r/)content(()char(\\b)content([^)char(\\W)content(a-z0-9_]+)char(\\b)content(\))delimiter(/)>operator(\))
+comment(#-----------------------------)
+ident(lowords) operator(=) ident(str)operator(.)ident(scan)operator(()regexp<delimiter(%r/)content(()char(\\b)content([^)char(\\W)content(A-Z0-9_]+)char(\\b)content(\))delimiter(/)>operator(\))
+comment(#-----------------------------)
+ident(icwords) operator(=) ident(str)operator(.)ident(scan)operator(()regexp<delimiter(%r/)content(()char(\\b)content([^)char(\\W)content(a-z0-9_][^)char(\\W)content(A-Z0-9_]*)char(\\b)content(\))delimiter(/)>operator(\))
+comment(#-----------------------------)
+ident(links) operator(=) ident(str)operator(.)ident(scan)operator(()regexp<delimiter(%r/)content(<A[^>]+?HREF)char(\\s)content(*=)char(\\s)content(*["']?([^'" >]+?\)[ '"]?>)delimiter(/)modifier(mi)>operator(\))
+comment(#-----------------------------)
+ident(initial) operator(=) ident(str) operator(=)operator(~) regexp<delimiter(/)content(^)char(\\S)content(+)char(\\s)content(+()char(\\S)content(\))char(\\S)content(*)char(\\s)content(+)char(\\S)delimiter(/)> operator(?) global_variable($1) operator(:) string<delimiter(")delimiter(")>
+comment(#-----------------------------)
+ident(str)operator(.)ident(gsub!)operator(()regexp<delimiter(%r/)content("([^"]*\)")delimiter(/)>operator(,) string<delimiter(%q-)content(``)content(\\1)content('')delimiter(-)>operator(\))
+comment(#-----------------------------)
+
+global_variable($/) operator(=) string<delimiter(")delimiter(")>
+ident(sentences) operator(=) operator([)operator(])
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(para)operator(|)
+ ident(para)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\n)delimiter(/)>operator(,) string<delimiter(')content( )delimiter(')>operator(\))
+ ident(para)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content( {3,})delimiter(/)>operator(,)string<delimiter(')content( )delimiter(')>operator(\))
+ ident(sentences) operator(<<) ident(para)operator(.)ident(scan)operator(()regexp<delimiter(/)content(()char(\\S)content(.*?[!?.]\)(?= |)char(\\Z)content(\))delimiter(/)>operator(\))
+reserved(end)
+
+comment(#-----------------------------)
+regexp<delimiter(%r/)content(()char(\\d)content({4}\)-()char(\\d)char(\\d)content(\)-()char(\\d)char(\\d)content(\))delimiter(/)> comment(# YYYY in $1, MM in $2, DD in $3)
+comment(#-----------------------------)
+regexp<delimiter(%r/)content( ^
+ (?:
+ 1 )char(\\s)content( (?: )char(\\d)char(\\d)char(\\d)content( )char(\\s)content(\)? # 1, or 1 and area code
+ | # ... or ...
+ )char(\\()char(\\d)char(\\d)char(\\d)char(\\\))content( )char(\\s)content( # area code with parens
+ | # ... or ...
+ (?: )char(\\+)char(\\d)char(\\d)content(?)char(\\d)content(? )char(\\s)content(\)? # optional +country code
+ )char(\\d)char(\\d)char(\\d)content( ([)char(\\s)char(\\-)content(]\) # and area code
+ \)
+ )char(\\d)char(\\d)char(\\d)content( ()char(\\s)content(|)char(\\1)content(\) # prefix (and area code separator\)
+ )char(\\d)char(\\d)char(\\d)char(\\d)content( # exchange
+ $
+ )delimiter(/)modifier(x)>
+comment(#-----------------------------)
+regexp<delimiter(%r/)char(\\b)content(oh)char(\\s)content(+my)char(\\s)content(+gh?o(d(dess(es\)?|s?\)|odness|sh\))char(\\b)delimiter(/)modifier(i)>
+comment(#-----------------------------)
+ident(lines) operator(=) operator([)operator(])
+ident(lines) operator(<<) global_variable($1) reserved(while) ident(input)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(^([^)char(\\012)char(\\015)content(]*\)()char(\\012)char(\\015)content(?|)char(\\015)char(\\012)content(?\))delimiter(/)>operator(,)string<delimiter(')delimiter(')>operator(\))
+
+
+comment(# @@PLEAC@@_7.0)
+comment(# An IO object being Enumerable, we can use 'each' directly on it)
+constant(File)operator(.)ident(open)operator(()string<delimiter(")content(/usr/local/widgets/data)delimiter(")>operator(\))operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ ident(puts) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)content(blue)delimiter(/)>
+operator(})
+
+ident(logfile) operator(=) constant(File)operator(.)ident(new)operator(()string<delimiter(")content(/var/log/rubylog.txt)delimiter(")>operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+ident(mysub)operator(()global_variable($stdin)operator(,) ident(logfile)operator(\))
+
+comment(# The method IO#readline is similar to IO#gets)
+comment(# but throws an exception when it reaches EOF)
+ident(f) operator(=) constant(File)operator(.)ident(new)operator(()string<delimiter(")content(bla.txt)delimiter(")>operator(\))
+reserved(begin)
+ reserved(while) operator(()ident(line) operator(=) ident(f)operator(.)ident(readline)operator(\))
+ ident(line)operator(.)ident(chomp)
+ global_variable($stdout)operator(.)ident(print) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)content(blue)delimiter(/)>
+ reserved(end)
+reserved(rescue) constant(EOFError)
+ ident(f)operator(.)ident(close)
+reserved(end)
+
+reserved(while) global_variable($stdin)operator(.)ident(gets) comment(# reads from STDIN)
+ reserved(unless) operator(()regexp<delimiter(/)char(\\d)delimiter(/)>operator(\))
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(No digit found.)delimiter(")> comment(# writes to STDERR)
+ reserved(end)
+ ident(puts) string<delimiter(")content(Read: )inline<delimiter(#{)global_variable($_)delimiter(})>delimiter(")> comment(# writes to STDOUT)
+reserved(end)
+
+ident(logfile) operator(=) constant(File)operator(.)ident(new)operator(()string<delimiter(")content(/tmp/log)delimiter(")>operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+
+ident(logfile)operator(.)ident(close)
+
+comment(# $defout (or its synonym '$>'\) is the destination of output)
+comment(# for Kernel#print, Kernel#puts, and family functions)
+ident(logfile) operator(=) constant(File)operator(.)ident(new)operator(()string<delimiter(")content(log.txt)delimiter(")>operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+ident(old) operator(=) global_variable($defout)
+global_variable($defout) operator(=) ident(logfile) comment(# switch to logfile for output)
+ident(puts) string<delimiter(")content(Countdown initiated ...)delimiter(")>
+global_variable($defout) operator(=) ident(old) comment(# return to original output)
+ident(puts) string<delimiter(")content(You have 30 seconds to reach minimum safety distance.)delimiter(")>
+
+
+comment(# @@PLEAC@@_7.1)
+ident(source) operator(=) constant(File)operator(.)ident(new)operator(()ident(path)operator(,) string<delimiter(")content(r)delimiter(")>operator(\)) comment(# open file "path" for reading only)
+ident(sink) operator(=) constant(File)operator(.)ident(new)operator(()ident(path)operator(,) string<delimiter(")content(w)delimiter(")>operator(\)) comment(# open file "path" for writing only)
+
+ident(source) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDONLY)operator(\)) comment(# open file "path" for reading only)
+ident(sink) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(\)) comment(# open file "path" for writing only)
+
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) string<delimiter(")content(r+)delimiter(")>operator(\)) comment(# open "path" for reading and writing)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) ident(flags)operator(\)) comment(# open "path" with the flags "flags" (see examples below for flags\))
+
+comment(# open file "path" read only)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) string<delimiter(")content(r)delimiter(")>operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDONLY)operator(\))
+
+comment(# open file "path" write only, create it if it does not exist)
+comment(# truncate it to zero length if it exists)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(TRUNC)operator(|)constant(File)operator(::)constant(CREAT)operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(TRUNC)operator(|)constant(File)operator(::)constant(CREAT)operator(,) integer(0666)operator(\)) comment(# with permission 0666)
+
+comment(# open file "path" write only, fails if file exists)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(EXCL)operator(|)constant(File)operator(::)constant(CREAT)operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(EXCL)operator(|)constant(File)operator(::)constant(CREAT)operator(,) integer(0666)operator(\))
+
+comment(# open file "path" for appending)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) string<delimiter(")content(a)delimiter(")>operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(APPEND)operator(|)constant(File)operator(::)constant(CREAT)operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(APPEND)operator(|)constant(File)operator(::)constant(CREAT)operator(,) integer(0666)operator(\))
+
+comment(# open file "path" for appending only when file exists)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(WRONLY)operator(|)constant(File)operator(::)constant(APPEND)operator(\))
+
+comment(# open file "path" for reading and writing)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) string<delimiter(")content(r+)delimiter(")>operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDWR)operator(\))
+
+comment(# open file for reading and writing, create a new file if it does not exist)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(CREAT)operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(CREAT)operator(,) integer(0600)operator(\))
+
+comment(# open file "path" reading and writing, fails if file exists)
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(EXCL)operator(|)constant(File)operator(::)constant(CREAT)operator(\))
+ident(file) operator(=) constant(File)operator(.)ident(open)operator(()ident(path)operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(EXCL)operator(|)constant(File)operator(::)constant(CREAT)operator(,) integer(0600)operator(\))
+
+
+comment(# @@PLEAC@@_7.2)
+comment(# No problem with Ruby since the filename doesn't contain characters with)
+comment(# special meaning; like Perl's sysopen)
+constant(File)operator(.)ident(open)operator(()ident(filename)operator(,) string<delimiter(')content(r)delimiter(')>operator(\))
+
+
+comment(# @@PLEAC@@_7.3)
+constant(File)operator(.)ident(expand_path)operator(()string<delimiter(')content(~root/tmp)delimiter(')>operator(\))
+comment(#=> "/root/tmp")
+constant(File)operator(.)ident(expand_path)operator(()string<delimiter(')content(~rpcuser)delimiter(')>operator(\))
+comment(#=> "/var/lib/nfs")
+
+comment(# To expand ~/.. it explicitely needs the environment variable HOME)
+constant(File)operator(.)ident(expand_path)operator(()string<delimiter(')content(~/tmp)delimiter(')>operator(\))
+comment(#=> "/home/gc/tmp")
+
+
+comment(# @@PLEAC@@_7.4)
+comment(# The exception raised in Ruby reports the filename)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(afile)delimiter(')>operator(\))
+
+
+comment(# @@PLEAC@@_7.5)
+comment(# Standard Ruby distribution provides the following useful extension)
+ident(require) string<delimiter(')content(tempfile)delimiter(')>
+comment(# With the Tempfile class, the file is automatically deleted on garbage)
+comment(# collection, so you won't need to remove it, later on.)
+ident(tf) operator(=) constant(Tempfile)operator(.)ident(new)operator(()string<delimiter(')content(tmp)delimiter(')>operator(\)) comment(# a name is required to create the filename)
+
+comment(# If you need to pass the filename to an external program you can use)
+comment(# File#path, but don't forget to File#flush in order to flush anything)
+comment(# living in some buffer somewhere.)
+ident(tf)operator(.)ident(flush)
+ident(system)operator(()string<delimiter(")content(/usr/bin/dowhatever )inline<delimiter(#{)ident(tf)operator(.)ident(path)delimiter(})>delimiter(")>operator(\))
+
+ident(fh) operator(=) constant(Tempfile)operator(.)ident(new)operator(()string<delimiter(')content(tmp)delimiter(')>operator(\))
+ident(fh)operator(.)ident(sync) operator(=) pre_constant(true) comment(# autoflushes)
+integer(10)operator(.)ident(times) operator({) operator(|)ident(i)operator(|) ident(fh)operator(.)ident(puts) ident(i) operator(})
+ident(fh)operator(.)ident(rewind)
+ident(puts) string<delimiter(')content(Tmp file has: )delimiter(')>operator(,) ident(fh)operator(.)ident(readlines)
+
+
+comment(# @@PLEAC@@_7.6)
+reserved(while) operator(()pre_constant(DATA)operator(.)ident(gets)operator(\)) reserved(do)
+ comment(# process the line )
+reserved(end)
+comment(__END__
+# your data goes here
+# __DATA__ doesn't exist in Ruby
+
+)comment(#CODE)
+comment(# get info about the script (size, date of last modification\))
+ident(kilosize) operator(=) pre_constant(DATA)operator(.)ident(stat)operator(.)ident(size) operator(/) integer(1024)
+ident(last_modif) operator(=) pre_constant(DATA)operator(.)ident(stat)operator(.)ident(mtime)
+ident(puts) string<delimiter(")content(<P>Script size is )inline<delimiter(#{)ident(kilosize)delimiter(})>delimiter(")>
+ident(puts) string<delimiter(")content(<P>Last script update: )inline<delimiter(#{)ident(last_modif)delimiter(})>delimiter(")>
+comment(__END__
+# DO NOT REMOVE THE PRECEEDING LINE.
+# Everything else in this file will be ignored.
+)comment(#CODE)
+
+
+comment(# @@PLEAC@@_7.7)
+reserved(while) ident(line) operator(=) ident(gets) reserved(do)
+ comment(# do something with line.)
+reserved(end)
+
+comment(# or )
+reserved(while) ident(gets) reserved(do)
+ comment(# do something with $_)
+reserved(end)
+
+comment(# or more rubyish)
+global_variable($stdin)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ comment(# do stuff with line)
+reserved(end)
+
+
+comment(# ARGF may makes this more easy)
+comment(# this is skipped if ARGV.size==0)
+pre_constant(ARGV)operator(.)ident(each) reserved(do) operator(|)ident(filename)operator(|)
+ comment(# closing and exception handling are done by the block)
+ ident(open)operator(()ident(filename)operator(\)) reserved(do) operator(|)ident(fd)operator(|)
+ ident(fd)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ comment(# do stuff with line)
+ reserved(end)
+ reserved(end) reserved(rescue) ident(abort)operator(()string<delimiter(")content(can't open %s)delimiter(")> operator(%) ident(filename)operator(\))
+reserved(end)
+
+comment(# globbing is done in the Dir module)
+pre_constant(ARGV) operator(=) constant(Dir)operator([)string<delimiter(")content(*.[Cch])delimiter(")>operator(]) reserved(if) pre_constant(ARGV)operator(.)ident(empty?)
+
+comment(# note: optparse is the preferred way to handle this)
+reserved(if) operator(()pre_constant(ARGV)operator([)integer(0)operator(]) operator(==) string<delimiter(')content(-c)delimiter(')>operator(\))
+ ident(chop_first) operator(+)operator(=) integer(1)
+ pre_constant(ARGV)operator(.)ident(shift)
+reserved(end)
+
+
+comment(# processing numerical options)
+reserved(if) pre_constant(ARGV)operator([)integer(0)operator(]) operator(=)operator(~) regexp<delimiter(/)content(^-()char(\\d)content(+\)$)delimiter(/)>
+ ident(columns) operator(=) global_variable($1)
+ pre_constant(ARGV)operator(.)ident(shift)
+reserved(end)
+
+comment(# again, better to use optparse:)
+ident(require) string<delimiter(')content(optparse)delimiter(')>
+ident(nostdout) operator(=) integer(0)
+ident(append) operator(=) integer(0)
+ident(unbuffer) operator(=) integer(0)
+ident(ignore_ints) operator(=) integer(0)
+pre_constant(ARGV)operator(.)ident(options) reserved(do) operator(|)ident(opt)operator(|)
+ ident(opt)operator(.)ident(on)operator(()string<delimiter(')content(-n)delimiter(')>operator(\)) operator({) ident(nostdout) operator(+)operator(=)integer(1) operator(})
+ ident(opt)operator(.)ident(on)operator(()string<delimiter(')content(-a)delimiter(')>operator(\)) operator({) ident(append) operator(+)operator(=)integer(1) operator(})
+ ident(opt)operator(.)ident(on)operator(()string<delimiter(')content(-u)delimiter(')>operator(\)) operator({) ident(unbuffer) operator(+)operator(=)integer(1) operator(})
+ ident(opt)operator(.)ident(on)operator(()string<delimiter(')content(-i)delimiter(')>operator(\)) operator({) ident(ignore_ints) operator(+)operator(=)integer(1) operator(})
+ ident(opt)operator(.)ident(parse!)
+reserved(end) reserved(or) ident(abort)operator(()string<delimiter(")content(usage: )delimiter(")> operator(+) pre_constant(__FILE__) operator(+) string<delimiter(")content( [-ainu] [filenames])delimiter(")>operator(\))
+
+comment(# no need to do undef $/, we have File.read)
+ident(str) operator(=) constant(File)operator(.)ident(read)operator(()pre_constant(ARGV)operator([)integer(0)operator(])operator(\))
+
+comment(# again we have File.read)
+ident(str) operator(=) constant(File)operator(.)ident(read)operator(()pre_constant(ARGV)operator([)integer(0)operator(])operator(\))
+
+comment(# not sure what this should do:)
+comment(# I believe open the file, print filename, lineno and line:)
+pre_constant(ARGF)operator(.)ident(each_with_index) reserved(do) operator(|)ident(line)operator(,) ident(idx)operator(|)
+ ident(print) pre_constant(ARGF)operator(.)ident(filename)operator(,) string<delimiter(")content(:)delimiter(")>operator(,) ident(idx)operator(,) string<delimiter(")content(;)delimiter(")>operator(,) ident(line)
+reserved(end)
+
+comment(# print all the lines in every file passed via command line that contains login)
+pre_constant(ARGF)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(puts) ident(line) reserved(if) ident(line) operator(=)operator(~) regexp<delimiter(/)content(login)delimiter(/)>
+reserved(end)
+comment(#)
+comment(# even this would fit)
+comment(#%ruby -ne "print if /f/" 2.log)
+comment(#)
+
+pre_constant(ARGF)operator(.)ident(each) operator({) operator(|)ident(l)operator(|) ident(puts) ident(l)operator(.)ident(downcase!) operator(})
+
+comment(#------------------)
+comment(#!/usr/bin/ruby -p)
+comment(# just like perl's -p)
+global_variable($_)operator(.)ident(downcase!)
+comment(#)
+
+comment(# I don't know who should I trust. )
+comment(# perl's version splits on \\w+ while python's on \\w.)
+
+ident(chunks) operator(=) integer(0)
+
+constant(File)operator(.)ident(read)operator(()pre_constant(ARGV)operator([)integer(0)operator(])operator(\))operator(.)ident(split)operator(.)ident(each) reserved(do) operator(|)ident(word)operator(|)
+ reserved(next) reserved(if) ident(word) operator(=)operator(~) regexp<delimiter(/)content(^#)delimiter(/)>
+ reserved(break) reserved(if) operator([)string<delimiter(")content(__DATA__)delimiter(")>operator(,) string<delimiter(")content(__END__)delimiter(")>operator(])operator(.)ident(member?) ident(word)
+ ident(chunks) operator(+)operator(=) integer(1)
+reserved(end)
+
+ident(print) string<delimiter(")content(Found )delimiter(")>operator(,) ident(chunks)operator(,) string<delimiter(")content( chunks)char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_7.8)
+ident(old) operator(=) constant(File)operator(.)ident(open)operator(()ident(old_file)operator(\))
+ident(new) operator(=) constant(File)operator(.)ident(open)operator(()ident(new_file)operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+reserved(while) ident(old)operator(.)ident(gets) reserved(do)
+ comment(# change $_, then...)
+ ident(new)operator(.)ident(print) global_variable($_)
+reserved(end)
+ident(old)operator(.)ident(close)
+ident(new)operator(.)ident(close)
+constant(File)operator(.)ident(rename)operator(()ident(old_file)operator(,) string<delimiter(")content(old.orig)delimiter(")>operator(\))
+constant(File)operator(.)ident(rename)operator(()ident(new_file)operator(,) ident(old_file)operator(\))
+
+reserved(while) ident(old)operator(.)ident(gets) reserved(do)
+ reserved(if) global_variable($.) operator(==) integer(20) reserved(then) comment(# we are at the 20th line)
+ ident(new)operator(.)ident(puts) string<delimiter(")content(Extra line 1)delimiter(")>
+ ident(new)operator(.)ident(puts) string<delimiter(")content(Extra line 2)delimiter(")>
+ reserved(end)
+ ident(new)operator(.)ident(print) global_variable($_)
+reserved(end)
+
+reserved(while) ident(old)operator(.)ident(gets) reserved(do)
+ reserved(next) reserved(if) integer(20)operator(..)integer(30) comment(# skip the 20th line to the 30th)
+ comment(# Ruby (and Perl\) permit to write if 20..30 )
+ comment(# instead of if (20 <= $.\) and ($. <= 30\))
+ ident(new)operator(.)ident(print) global_variable($_)
+reserved(end)
+
+
+comment(# @@PLEAC@@_7.9)
+comment(#% ruby -i.orig -pe 'FILTER COMMAND' file1 file2 file3 ...)
+comment(#)
+comment(#-----------------------------)
+comment(##!/usr/bin/ruby -i.orig -p)
+comment(# filter commands go here)
+comment(#-----------------------------)
+
+comment(#% ruby -pi.orig -e 'gsub!(/DATE/\){Time.now\)')
+
+comment(# effectively becomes:)
+pre_constant(ARGV) operator(<<) string<delimiter(')content(I)delimiter(')>
+ident(oldfile) operator(=) string<delimiter(")delimiter(")>
+reserved(while) ident(gets)
+ reserved(if) pre_constant(ARGF)operator(.)ident(filename) operator(!)operator(=) ident(oldfile)
+ ident(newfile) operator(=) pre_constant(ARGF)operator(.)ident(filename)
+ constant(File)operator(.)ident(rename)operator(()ident(newfile)operator(,) ident(newfile) operator(+) string<delimiter(")content(.orig)delimiter(")>operator(\))
+ global_variable($stdout) operator(=) constant(File)operator(.)ident(open)operator(()ident(newfile)operator(,)string<delimiter(')content(w)delimiter(')>operator(\))
+ ident(oldfile) operator(=) ident(newfile)
+ reserved(end)
+ ident(gsub!)operator(()regexp<delimiter(/)content(DATE)delimiter(/)>operator(\))operator({)constant(Time)operator(.)ident(now)operator(})
+ ident(print)
+reserved(end)
+global_variable($stdout) operator(=) constant(STDOUT)
+comment(#-----------------------------)
+comment(#% ruby -i.old -pe 'gsub!(%r{\\bhisvar\\b}, 'hervar'\)' *.[Cchy])
+
+comment(#-----------------------------)
+comment(# set up to iterate over the *.c files in the current directory,)
+comment(# editing in place and saving the old file with a .orig extension)
+global_variable($-i) operator(=) string<delimiter(')content(.orig)delimiter(')> comment(# set up -i mode)
+pre_constant(ARGV)operator(.)ident(replace)operator(()constant(Dir)operator([)string<delimiter(')content(*.[Cchy])delimiter(')>operator(])operator(\))
+reserved(while) ident(gets)
+ reserved(if) global_variable($.) operator(==) integer(1)
+ ident(print) string<delimiter(")content(This line should appear at the top of each file)char(\\n)delimiter(")>
+ reserved(end)
+ ident(gsub!)operator(()regexp<delimiter(/)char(\\b)content((p\)earl)char(\\b)delimiter(/)modifier(i)>operator(,) string<delimiter(')content(\\1)content(erl)delimiter(')>operator(\)) comment(# Correct typos, preserving case)
+ ident(print)
+ pre_constant(ARGF)operator(.)ident(close) reserved(if) pre_constant(ARGF)operator(.)ident(eof)
+reserved(end)
+
+
+comment(# @@PLEAC@@_7.10)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(itest)delimiter(')>operator(,) string<delimiter(')content(r+)delimiter(')>operator(\)) reserved(do) operator(|)ident(f)operator(|) comment(# open file for update)
+ ident(lines) operator(=) ident(f)operator(.)ident(readlines) comment(# read into array of lines)
+ ident(lines)operator(.)ident(each) reserved(do) operator(|)ident(it)operator(|) comment(# modify lines)
+ ident(it)operator(.)ident(gsub!)operator(()regexp<delimiter(/)content(foo)delimiter(/)>operator(,) string<delimiter(')content(QQQ)delimiter(')>operator(\))
+ reserved(end)
+ ident(f)operator(.)ident(pos) operator(=) integer(0) comment(# back to start)
+ ident(f)operator(.)ident(print) ident(lines) comment(# write out modified lines)
+ ident(f)operator(.)ident(truncate)operator(()ident(f)operator(.)ident(pos)operator(\)) comment(# truncate to new length)
+reserved(end) comment(# file is automatically closed)
+comment(#-----------------------------)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(itest)delimiter(')>operator(,) string<delimiter(')content(r+)delimiter(')>operator(\)) reserved(do) operator(|)ident(f)operator(|)
+ ident(out) operator(=) string<delimiter(")delimiter(")>
+ ident(f)operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(out) operator(<<) ident(line)operator(.)ident(gsub)operator(()regexp<delimiter(/)content(DATE)delimiter(/)>operator(\)) operator({)constant(Time)operator(.)ident(now)operator(})
+ reserved(end)
+ ident(f)operator(.)ident(pos) operator(=) integer(0)
+ ident(f)operator(.)ident(print) ident(out)
+ ident(f)operator(.)ident(truncate)operator(()ident(f)operator(.)ident(pos)operator(\))
+reserved(end)
+
+comment(# @@PLEAC@@_7.11)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(infile)delimiter(')>operator(,) string<delimiter(')content(r+)delimiter(')>operator(\)) reserved(do) operator(|)ident(f)operator(|)
+ ident(f)operator(.)ident(flock) constant(File)operator(::)constant(LOCK_EX)
+ comment(# update file)
+reserved(end)
+comment(#-----------------------------)
+constant(File)operator(::)constant(LOCK_SH) comment(# shared lock (for reading\))
+constant(File)operator(::)constant(LOCK_EX) comment(# exclusive lock (for writing\))
+constant(File)operator(::)constant(LOCK_NB) comment(# non-blocking request)
+constant(File)operator(::)constant(LOCK_UN) comment(# free lock)
+comment(#-----------------------------)
+reserved(unless) ident(f)operator(.)ident(flock) constant(File)operator(::)constant(LOCK_EX) operator(|) constant(File)operator(::)constant(LOCK_NB)
+ ident(warn) string<delimiter(")content(can't get immediate lock: blocking ...)delimiter(")>
+ ident(f)operator(.)ident(flock) constant(File)operator(::)constant(LOCK_EX)
+reserved(end)
+comment(#-----------------------------)
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(numfile)delimiter(')>operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(CREAT)operator(\)) reserved(do) operator(|)ident(f)operator(|)
+ ident(f)operator(.)ident(flock)operator(()constant(File)operator(::)constant(LOCK_EX)operator(\))
+ ident(num) operator(=) ident(f)operator(.)ident(gets)operator(.)ident(to_i) operator(||) integer(0)
+ ident(f)operator(.)ident(pos) operator(=) integer(0)
+ ident(f)operator(.)ident(truncate) integer(0)
+ ident(f)operator(.)ident(puts) ident(num) operator(+) integer(1)ident(q)
+reserved(end)
+
+
+comment(# @@PLEAC@@_7.12)
+ident(output_handle)operator(.)ident(sync) operator(=) pre_constant(true)
+comment(# Please note that like in Perl, $stderr is already unbuffered)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# seeme - demo stdio output buffering)
+global_variable($stdout)operator(.)ident(sync) operator(=) pre_constant(ARGV)operator(.)ident(size) operator(>) integer(0)
+ident(print) string<delimiter(")content(Now you don't see it...)delimiter(")>
+ident(sleep) integer(2)
+ident(puts) string<delimiter(")content(now you do)delimiter(")>
+comment(#-----------------------------)
+global_variable($stderr)operator(.)ident(sync) operator(=) pre_constant(true)
+ident(afile)operator(.)ident(sync) operator(=) pre_constant(false)
+comment(#-----------------------------)
+comment(# assume 'remote_con' is an interactive socket handle,)
+comment(# but 'disk_file' is a handle to a regular file.)
+ident(remote_con)operator(.)ident(sync) operator(=) pre_constant(true) comment(# unbuffer for clarity)
+ident(disk_file)operator(.)ident(sync) operator(=) pre_constant(false) comment(# buffered for speed)
+comment(#-----------------------------)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+ident(sock) operator(=) constant(TCPSocket)operator(.)ident(new)operator(()string<delimiter(')content(www.ruby-lang.org)delimiter(')>operator(,) integer(80)operator(\))
+ident(sock)operator(.)ident(sync) operator(=) pre_constant(true)
+ident(sock)operator(.)ident(puts) string<delimiter(")content(GET /en/ HTTP/1.0 )char(\\n)char(\\n)delimiter(")>
+ident(resp) operator(=) ident(sock)operator(.)ident(read)
+ident(print) string<delimiter(")content(DOC IS: )inline<delimiter(#{)ident(resp)delimiter(})>char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_7.13)
+comment(#-----------------------------)
+comment(# assumes fh1, fh2, fh2 are oen IO objects)
+ident(nfound) operator(=) ident(select)operator(()operator([)global_variable($stdin)operator(,) ident(fh1)operator(,) ident(fh2)operator(,) ident(fh3)operator(])operator(,) pre_constant(nil)operator(,) pre_constant(nil)operator(,) integer(0)operator(\))
+ident(nfound)operator([)integer(0)operator(])operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ reserved(case) ident(file)
+ reserved(when) ident(fh1)
+ comment(# do something with fh1)
+ reserved(when) ident(fh2)
+ comment(# do something with fh2)
+ reserved(when) ident(fh3)
+ comment(# do something with fh3)
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+ident(input_files) operator(=) operator([)operator(])
+comment(# repeat next line for all in-files to poll)
+ident(input_files) operator(<<) ident(fh1)
+reserved(if) ident(nfound) operator(=) ident(select)operator(()ident(input_files)operator(,) pre_constant(nil)operator(,) pre_constant(nil)operator(,) integer(0)operator(\))
+ comment(# input ready on files in nfound[0])
+reserved(end)
+
+
+comment(# @@PLEAC@@_8.0)
+comment(#-----------------------------)
+comment(# datafile is a file or IO object)
+ident(datafile)operator(.)ident(readlines)operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ ident(line)operator(.)ident(chomp!)
+ ident(size) operator(=) ident(line)operator(.)ident(length)
+ ident(puts) ident(size)
+operator(})
+comment(#-----------------------------)
+ident(datafile)operator(.)ident(readlines)operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ ident(puts) ident(line)operator(.)ident(chomp!)operator(.)ident(length)
+operator(})
+comment(#-----------------------------)
+ident(lines) operator(=) ident(datafile)operator(.)ident(readlines)
+comment(#-----------------------------)
+ident(whole_file) operator(=) ident(file)operator(.)ident(read)
+comment(#-----------------------------)
+comment(# ruby -040 -e 'word = gets; puts "First word is #{word}"')
+comment(#-----------------------------)
+comment(# ruby -ne 'BEGIN { $/="%%\\n" }; $_.chomp; puts $_ if( $_=~/Unix/i\)' fortune.dat)
+comment(#-----------------------------)
+ident(handle)operator(.)ident(print) string<delimiter(")content(one)delimiter(")>operator(,) string<delimiter(")content(two)delimiter(")>operator(,) string<delimiter(")content(three)delimiter(")> comment(# "onetwothree")
+ident(puts) string<delimiter(")content(Baa baa black sheep.)delimiter(")> comment(# sent to $stdout)
+comment(#-----------------------------)
+ident(buffer) operator(=) ident(handle)operator(.)ident(read)operator(()integer(4096)operator(\))
+ident(rv) operator(=) ident(buffer)operator(.)ident(length)
+comment(#-----------------------------)
+ident(handle)operator(.)ident(truncate)operator(()ident(length)operator(\))
+ident(open)operator(()string<delimiter(")content(/tmp)inline<delimiter(#{)global_variable($$)delimiter(})>content(.pid)delimiter(")>operator(,) string<delimiter(')content(w)delimiter(')>operator(\)) operator({) operator(|)ident(handle)operator(|) ident(handle)operator(.)ident(truncate)operator(()ident(length)operator(\)) operator(})
+comment(#-----------------------------)
+ident(pos) operator(=) ident(datafile)operator(.)ident(pos) comment(# tell is an alias of pos)
+ident(puts) string<delimiter(")content(I'm )inline<delimiter(#{)ident(pos)delimiter(})>content( bytes from the start of datafile)delimiter(")>
+comment(#-----------------------------)
+ident(logfile)operator(.)ident(seek)operator(()integer(0)operator(,) constant(IO)operator(::)constant(SEEK_END)operator(\))
+ident(datafile)operator(.)ident(seek)operator(()ident(pos)operator(\)) comment(# IO::SEEK_SET is the default)
+ident(out)operator(.)ident(seek)operator(()operator(-)integer(20)operator(,) constant(IO)operator(::)constant(SEEK_CUR)operator(\))
+comment(#-----------------------------)
+ident(written) operator(=) ident(datafile)operator(.)ident(syswrite)operator(()ident(mystring)operator(\))
+ident(raise) constant(RunTimeError) reserved(unless) ident(written) operator(==) ident(mystring)operator(.)ident(length)
+ident(block) operator(=) ident(infile)operator(.)ident(sysread)operator(()integer(256)operator(\)) comment(# no equivalent to perl offset parameter in sysread)
+ident(puts) string<delimiter(")content(only read )inline<delimiter(#{)ident(block)operator(.)ident(length)delimiter(})>content( bytes)delimiter(")> reserved(if) integer(256) operator(!)operator(=) ident(block)operator(.)ident(length)
+comment(#-----------------------------)
+ident(pos) operator(=) ident(handle)operator(.)ident(sysseek)operator(()integer(0)operator(,) constant(IO)operator(::)constant(SEEK_CUR)operator(\)) comment(# don't change position)
+
+
+comment(# @@PLEAC@@_8.1)
+reserved(while) operator(()ident(line) operator(=) ident(fh)operator(.)ident(gets)operator(\))
+ ident(line)operator(.)ident(chomp!)
+ ident(nextline) operator(=) pre_constant(nil)
+ ident(line)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\\\)content($)delimiter(/)>operator(\)) operator({) operator(|)ident(match)operator(|) ident(nextline) operator(=) ident(fh)operator(.)ident(gets)operator(;) string<delimiter(')delimiter(')> operator(})
+ reserved(if) operator(()ident(nextline) operator(!)operator(=) pre_constant(nil)operator(\))
+ ident(line) operator(+)operator(=) ident(nextline)
+ reserved(redo)
+ reserved(end)
+ comment(# process full record in line here)
+reserved(end)
+comment(#-----------------------------)
+comment(# DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) \\)
+comment(# $(TEXINFOS\) $(INFOS\) $(MANS\) $(DATA\))
+comment(# DEP_DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) \\)
+comment(# $(TEXINFOS\) $(INFO_DEPS\) $(MANS\) $(DATA\) \\)
+comment(# $(EXTRA_DIST\))
+comment(#-----------------------------)
+ident(line)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\\\)char(\\s)content(*$)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\)) operator({)
+ comment(# as before)
+operator(})
+
+
+comment(# @@PLEAC@@_8.2)
+comment(#-----------------------------)
+ident(count) operator(=) shell<delimiter(`)content(wc -l < )inline<delimiter(#{)ident(filename)delimiter(})>delimiter(`)>
+ident(fail) string<delimiter(")content(wc failed: )inline<delimiter(#{)global_variable($?)delimiter(})>delimiter(")> reserved(if) global_variable($?) operator(!)operator(=) integer(0)
+ident(count)operator(.)ident(chomp!)
+comment(#-----------------------------)
+ident(count) operator(=) integer(0)
+constant(File)operator(.)ident(open)operator(()ident(file)operator(,) string<delimiter(')content(r)delimiter(')>operator(\)) operator({) operator(|)ident(fh)operator(|)
+ ident(count) operator(+)operator(=) integer(1) reserved(while) ident(fh)operator(.)ident(gets)
+operator(})
+comment(# count now holds the number of lines read)
+comment(#-----------------------------)
+ident(count) operator(=) integer(0)
+reserved(while) operator(()ident(chunk) operator(=) ident(file)operator(.)ident(sysread)operator(()integer(2)operator(**)integer(16)operator(\))operator(\))
+ ident(count) operator(+)operator(=) ident(chunk)operator(.)ident(count)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\))
+reserved(end) reserved(rescue) constant(EOFError)
+comment(#-----------------------------)
+constant(File)operator(.)ident(open)operator(()ident(filename)operator(,)string<delimiter(')content(r)delimiter(')>operator(\)) operator({) operator(|)ident(fh)operator(|)
+ ident(count) operator(+)operator(=) integer(1) reserved(while) ident(fh)operator(.)ident(gets)
+operator(})
+comment(# count now holds the number of lines read)
+comment(#-----------------------------)
+comment(# As ruby doesn't quite have an equivalent to using a for)
+comment(# statement as in perl, I threw this in)
+ident(count) operator(=) constant(File)operator(.)ident(readlines)operator(()ident(filename)operator(\))operator(.)ident(size)
+comment(#-----------------------------)
+integer(1) reserved(while) ident(file)operator(.)ident(gets)
+ident(count) operator(=) global_variable($.)
+comment(#-----------------------------)
+global_variable($/) operator(=) string<delimiter(')delimiter(')>
+ident(open)operator(()ident(filename)operator(,) string<delimiter(')content(r)delimiter(')>operator(\)) operator({) operator(|)ident(fh)operator(|)
+ integer(1) reserved(while) ident(fh)operator(.)ident(gets)
+ ident(para_count) operator(=) global_variable($.)
+operator(}) reserved(rescue) ident(fail)operator(()string<delimiter(")content(can't open )inline<delimiter(#{)ident(filename)delimiter(})>content(: $!)delimiter(")>operator(\))
+comment(#-----------------------------)
+
+
+comment(# ^^PLEAC^^_8.3)
+comment(#-----------------------------)
+reserved(while) operator(()ident(gets)operator(\))
+ ident(split)operator(.)ident(each) operator({) operator(|)ident(chunk)operator(|)
+ comment(# do something with chunk)
+ operator(})
+reserved(end)
+comment(#-----------------------------)
+reserved(while) operator(()ident(gets)operator(\))
+ ident(gsub)operator(()regexp<delimiter(/)content(()char(\\w)content([)char(\\w)content('-]*\))delimiter(/)>operator(\)) operator({) operator(|)ident(word)operator(|)
+ comment(# do something with word)
+ operator(})
+reserved(end)
+comment(#-----------------------------)
+comment(# Make a word frequency count)
+comment(# normally hashes can be created using {} or just Hash.new)
+comment(# but we want the default value of an entry to be 0 instead )
+comment(# of nil. (nil can't be incremented\))
+ident(seen) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(0)operator(\))
+reserved(while) operator(()ident(gets)operator(\))
+ ident(gsub)operator(()regexp<delimiter(/)content(()char(\\w)content([)char(\\w)content('-]*\))delimiter(/)>operator(\)) operator({) operator(|)ident(word)operator(|)
+ ident(seen)operator([)ident(word)operator(.)ident(downcase)operator(]) operator(+)operator(=) integer(1)
+ operator(})
+reserved(end)
+comment(# output hash in a descending numeric sort of its values)
+ident(seen)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(b)operator([)integer(1)operator(]) operator(<=>) ident(a)operator([)integer(1)operator(]) operator(})operator(.)ident(each) reserved(do) operator(|)ident(k)operator(,)ident(v)operator(|)
+ ident(printf)operator(()string<delimiter(")content(%5d %s)char(\\n)delimiter(")>operator(,) ident(v)operator(,) ident(k) operator(\))
+reserved(end)
+
+comment(#-----------------------------)
+comment(# Line frequency count)
+ident(seen) operator(=) constant(Hash)operator(.)ident(new)operator(()integer(0)operator(\))
+reserved(while) operator(()ident(gets)operator(\))
+ ident(seen)operator([)global_variable($_)operator(.)ident(downcase)operator(]) operator(+)operator(=) integer(1)
+reserved(end)
+ident(seen)operator(.)ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(b)operator([)integer(1)operator(]) operator(<=>) ident(a)operator([)integer(1)operator(]) operator(})operator(.)ident(each) reserved(do) operator(|)ident(k)operator(,)ident(v)operator(|)
+ ident(printf)operator(()string<delimiter(")content(%5d %s)char(\\n)delimiter(")>operator(,) ident(v)operator(,) ident(k) operator(\))
+reserved(end)
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_8.4)
+comment(#-----------------------------)
+comment(# instead of file handle FILE, we can just)
+comment(# use a string containing the filename)
+constant(File)operator(.)ident(readlines)operator(()ident(file)operator(\))operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ comment(# do something with line)
+operator(})
+comment(#-----------------------------)
+constant(File)operator(.)ident(readlines)operator(()ident(file)operator(\))operator(.)ident(reverse_each) operator({) operator(|)ident(line)operator(|)
+ comment(# do something with line)
+operator(})
+comment(#-----------------------------)
+comment(# the variable lines might have been created)
+comment(# this way)
+comment(# lines = File.readlines(file\))
+comment(#)
+comment(# normally one would use the reverse_each, but)
+comment(# if you insist on using a numerical index to)
+comment(# iterate over the lines array...)
+operator(()ident(lines)operator(.)ident(size) operator(-) integer(1)operator(\))operator(.)ident(downto)operator(()integer(0)operator(\)) operator({) operator(|)ident(i)operator(|)
+ ident(line) operator(=) ident(lines)operator([)ident(i)operator(])
+operator(})
+comment(#-----------------------------)
+comment(# the second readlines argument is a the )
+comment(# record separator $/, just like perl, a blank)
+comment(# separator splits the records into paragraphs)
+constant(File)operator(.)ident(readlines)operator(()ident(file)operator(,) string<delimiter(')delimiter(')>operator(\))operator(.)ident(each) operator({) operator(|)ident(paragraph)operator(|)
+ comment(# do something with paragraph)
+ ident(puts) string<delimiter(")content(->Paragraph )inline<delimiter(#{)ident(paragraph)delimiter(})>delimiter(")>
+operator(})
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_8.6)
+
+global_variable($/) operator(=) string<delimiter(")content(%)char(\\n)delimiter(")>operator(;)
+ident(srand)operator(;)
+
+constant(File)operator(.)ident(open)operator(()string<delimiter(')content(/usr/share/fortune/humorists)delimiter(')>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(line)operator(|)
+ ident(adage) operator(=) ident(line) reserved(if) ident(rand)operator(()global_variable($.)operator(\)) operator(<) integer(1)
+reserved(end)
+
+ident(puts) ident(adage)operator(;)
+
+
+comment(# @@PLEAC@@_8.10)
+reserved(begin)
+ ident(fh) operator(=) constant(File)operator(.)ident(open)operator(()ident(file)operator(,) string<delimiter(")content(r+)delimiter(")>operator(\))
+ ident(addr) operator(=) ident(fh)operator(.)ident(tell) reserved(unless) ident(fh)operator(.)ident(eof) reserved(while) ident(fh)operator(.)ident(gets)
+ ident(fh)operator(.)ident(truncate)operator(()ident(addr)operator(\))
+reserved(rescue) constant(SystemCallError)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")escape(#)global_variable($!)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.0)
+ident(entry) operator(=) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(/usr/bin/vi)delimiter(")>operator(\))
+ident(entry) operator(=) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(/usr/bin)delimiter(")>operator(\))
+ident(entry) operator(=) constant(File)operator(.)ident(stat)operator(()constant(INFILE)operator(\))
+
+ident(entry) operator(=) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(/usr/bin/vi)delimiter(")>operator(\))
+ident(ctime) operator(=) ident(entry)operator(.)ident(ctime)
+ident(size) operator(=) ident(entry)operator(.)ident(size)
+
+ident(f) operator(=) constant(File)operator(.)ident(open)operator(()ident(filename)operator(,) string<delimiter(")content(r)delimiter(")>operator(\))
+
+comment(## There is no -T equivalent in Ruby, but we can still test emptiness)
+reserved(if) ident(test)operator(()integer(?s)operator(,) ident(filename)operator(\))
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(filename)delimiter(})>content( doesn't have text in it.)delimiter(")>
+ ident(exit)
+reserved(end)
+
+constant(Dir)operator(.)ident(new)operator(()string<delimiter(")content(/usr/bin)delimiter(")>operator(\))operator(.)ident(each) reserved(do) operator(|)ident(filename)operator(|)
+ ident(puts) string<delimiter(")content(Inside /usr/bin is something called )inline<delimiter(#{)ident(filename)delimiter(})>delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.1)
+ident(file) operator(=) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(filename)delimiter(")>operator(\))
+ident(readtime)operator(,) ident(writetime) operator(=) ident(file)operator(.)ident(atime)operator(,) ident(file)operator(.)ident(mtime)
+ident(file)operator(.)ident(utime)operator(()ident(readtime)operator(,) ident(writetime)operator(\))
+
+constant(SECONDS_PER_DAY) operator(=) integer(60) operator(*) integer(60) operator(*) integer(24)
+ident(file) operator(=) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(filename)delimiter(")>operator(\))
+ident(atime)operator(,) ident(mtime) operator(=) ident(file)operator(.)ident(atime)operator(,) ident(file)operator(.)ident(mtime)
+
+ident(atime) operator(-)operator(=) integer(7) operator(*) constant(SECONDS_PER_DAY)
+ident(mtime) operator(-)operator(=) integer(7) operator(*) constant(SECONDS_PER_DAY)
+
+constant(File)operator(.)ident(utime)operator(()ident(atime)operator(,) ident(mtime)operator(,) ident(file)operator(\))
+ident(mtime) operator(=) constant(File)operator(.)ident(stat)operator(()ident(file)operator(\))operator(.)ident(mtime)
+constant(File)operator(.)ident(utime)operator(()constant(Time)operator(.)ident(new)operator(,) ident(mtime)operator(,) ident(file)operator(\))
+constant(File)operator(.)ident(utime)operator(()constant(Time)operator(.)ident(new)operator(,) constant(File)operator(.)ident(stat)operator(()string<delimiter(")content(testfile)delimiter(")>operator(\))operator(.)ident(mtime)operator(,) ident(file)operator(\))
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(## uvi - vi a file without changing it's access times)
+
+reserved(if) pre_constant(ARGV)operator(.)ident(length) operator(!)operator(=) integer(1)
+ ident(puts) string<delimiter(")content(usage: uvi filename)delimiter(")>
+ ident(exit)
+reserved(end)
+ident(file) operator(=) pre_constant(ARGV)operator([)integer(0)operator(])
+ident(atime)operator(,) ident(mtime) operator(=) constant(File)operator(.)ident(stat)operator(()ident(file)operator(\))operator(.)ident(atime)operator(,) constant(File)operator(.)ident(stat)operator(()ident(file)operator(\))operator(.)ident(mtime)
+ident(system)operator(()constant(ENV)operator([)string<delimiter(")content(EDITOR)delimiter(")>operator(]) operator(||) string<delimiter(")content(vi)delimiter(")>operator(,) ident(file)operator(\))
+constant(File)operator(.)ident(utime)operator(()ident(atime)operator(,) ident(mtime)operator(,) ident(file)operator(\))
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_9.2)
+constant(File)operator(.)ident(unlink)operator(()constant(FILENAME)operator(\))
+
+ident(err_flg) operator(=) pre_constant(false)
+ident(filenames)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ reserved(begin)
+ constant(File)operator(.)ident(unlink)operator(()ident(file)operator(\))
+ reserved(rescue)
+ ident(err_flg) operator(=) global_variable($!)
+ reserved(end)
+reserved(end)
+ident(err_flg) reserved(and) ident(raise) string<delimiter(")content(Couldn't unlink all of )inline<delimiter(#{)ident(filenames)operator(.)ident(join)operator(()string<delimiter(")content( )delimiter(")>operator(\))delimiter(})>content(: )inline<delimiter(#{)ident(err_flg)delimiter(})>delimiter(")>
+
+constant(File)operator(.)ident(unlink)operator(()ident(file)operator(\))
+
+ident(count) operator(=) ident(filenames)operator(.)ident(length)
+ident(filenames)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ reserved(begin)
+ constant(File)operator(.)ident(unlink)operator(()ident(file)operator(\))
+ reserved(rescue)
+ ident(count) operator(-)operator(=) integer(1)
+ reserved(end)
+reserved(end)
+reserved(if) ident(count) operator(!)operator(=) ident(filenames)operator(.)ident(length)
+ constant(STDERR)operator(.)ident(puts) string<delimiter(")content(could only delete )inline<delimiter(#{)ident(count)delimiter(})>content( of )inline<delimiter(#{)ident(filenames)operator(.)ident(length)delimiter(})>content( files)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.3)
+ident(require) string<delimiter(")content(ftools)delimiter(")>
+constant(File)operator(.)ident(copy)operator(()ident(oldfile)operator(,) ident(newfile)operator(\))
+
+ident(infile) operator(=) constant(File)operator(.)ident(open)operator(()ident(oldfile)operator(,) string<delimiter(")content(r)delimiter(")>operator(\))
+ident(outfile) operator(=) constant(File)operator(.)ident(open)operator(()ident(newfile)operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+
+ident(blksize) operator(=) ident(infile)operator(.)ident(stat)operator(.)ident(blksize)
+comment(# This doesn't handle partial writes or ^Z)
+comment(# like the Perl version does.)
+reserved(while) operator(()ident(line) operator(=) ident(infile)operator(.)ident(read)operator(()ident(blksize)operator(\))operator(\))
+ ident(outfile)operator(.)ident(write)operator(()ident(line)operator(\))
+reserved(end)
+
+ident(infile)operator(.)ident(close)
+ident(outfile)operator(.)ident(close)
+
+ident(system)operator(()string<delimiter(")content(cp )inline<delimiter(#{)ident(oldfile)delimiter(})>content( )inline<delimiter(#{)ident(newfile)delimiter(})>delimiter(")>operator(\)) comment(# unix)
+ident(system)operator(()string<delimiter(")content(copy )inline<delimiter(#{)ident(oldfile)delimiter(})>content( )inline<delimiter(#{)ident(newfile)delimiter(})>delimiter(")>operator(\)) comment(# dos, vms)
+
+ident(require) string<delimiter(")content(ftools)delimiter(")>
+constant(File)operator(.)ident(copy)operator(()string<delimiter(")content(datafile.dat)delimiter(")>operator(,) string<delimiter(")content(datafile.bak)delimiter(")>operator(\))
+constant(File)operator(.)ident(move)operator(()string<delimiter(")content(datafile.new)delimiter(")>operator(,) string<delimiter(")content(datafile.dat)delimiter(")>operator(\))
+
+
+comment(# @@PLEAC@@_9.4)
+global_variable($seen) operator(=) operator({)operator(}) comment(# must use global var to be seen inside of method below)
+
+reserved(def) method(do_my_thing)operator(()ident(filename)operator(\))
+ ident(dev)operator(,) ident(ino) operator(=) constant(File)operator(.)ident(stat)operator(()ident(filename)operator(\))operator(.)ident(dev)operator(,) constant(File)operator(.)ident(stat)operator(()ident(filename)operator(\))operator(.)ident(ino)
+ reserved(unless) global_variable($seen)operator([)operator([)ident(dev)operator(,) ident(ino)operator(])operator(])
+ comment(# do something with $filename because we haven't)
+ comment(# seen it before)
+ reserved(end)
+ global_variable($seen)operator([)operator([)ident(dev)operator(,) ident(ino)operator(])operator(]) operator(=) global_variable($seen)operator([)operator([)ident(dev)operator(,) ident(ino)operator(])operator(])operator(.)ident(to_i) operator(+) integer(1)
+reserved(end)
+
+ident(files)operator(.)ident(each) reserved(do) operator(|)ident(filename)operator(|)
+ ident(dev)operator(,) ident(ino) operator(=) constant(File)operator(.)ident(stat)operator(()ident(filename)operator(\))operator(.)ident(dev)operator(,) constant(File)operator(.)ident(stat)operator(()ident(filename)operator(\))operator(.)ident(ino)
+ reserved(if) operator(!)global_variable($seen)operator(.)ident(has_key?)operator(()operator([)ident(dev)operator(,) ident(ino)operator(])operator(\))
+ global_variable($seen)operator([)operator([)ident(dev)operator(,) ident(ino)operator(])operator(]) operator(=) operator([)operator(])
+ reserved(end)
+ global_variable($seen)operator([)operator([)ident(dev)operator(,) ident(ino)operator(])operator(])operator(.)ident(push)operator(()ident(filename)operator(\))
+reserved(end)
+
+global_variable($seen)operator(.)ident(keys)operator(.)ident(sort)operator(.)ident(each) reserved(do) operator(|)ident(devino)operator(|)
+ ident(ino)operator(,) ident(dev) operator(=) ident(devino)
+ reserved(if) global_variable($seen)operator([)ident(devino)operator(])operator(.)ident(length) operator(>) integer(1)
+ comment(# $seen[devino] is a list of filenames for the same file)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.5)
+constant(Dir)operator(.)ident(open)operator(()ident(dirname)operator(\)) reserved(do) operator(|)ident(dir)operator(|)
+ ident(dir)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ comment(# do something with dirname/file)
+ ident(puts) ident(file)
+ reserved(end)
+reserved(end)
+comment(# Dir.close is automatic)
+
+comment(# No -T equivalent in Ruby)
+
+ident(dir)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ reserved(next) reserved(if) ident(file) operator(=)operator(~) regexp<delimiter(/)content(^)char(\\.)char(\\.)content(?$)delimiter(/)>
+ comment(# ...)
+reserved(end)
+
+reserved(def) method(plainfiles)operator(()ident(dir)operator(\))
+ ident(dh) operator(=) constant(Dir)operator(.)ident(open)operator(()ident(dir)operator(\))
+ ident(dh)operator(.)ident(entries)operator(.)ident(grep)operator(()regexp<delimiter(/)content(^[^.])delimiter(/)>operator(\))operator(.)
+ ident(map) operator({)operator(|)ident(file)operator(|) string<delimiter(")inline<delimiter(#{)ident(dir)delimiter(})>content(/)inline<delimiter(#{)ident(file)delimiter(})>delimiter(")>operator(})operator(.)
+ ident(find_all) operator({)operator(|)ident(file)operator(|) ident(test)operator(()integer(?f)operator(,) ident(file)operator(\))operator(})operator(.)
+ ident(sort)
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.6)
+ident(list) operator(=) constant(Dir)operator(.)ident(glob)operator(()string<delimiter(")content(*.c)delimiter(")>operator(\))
+
+ident(dir) operator(=) constant(Dir)operator(.)ident(open)operator(()ident(path)operator(\))
+ident(files) operator(=) ident(dir)operator(.)ident(entries)operator(.)ident(grep)operator(()regexp<delimiter(/)char(\\.)content(c$)delimiter(/)>operator(\))
+ident(dir)operator(.)ident(close)
+
+ident(files) operator(=) constant(Dir)operator(.)ident(glob)operator(()string<delimiter(")content(*.c)delimiter(")>operator(\))
+ident(files) operator(=) constant(Dir)operator(.)ident(open)operator(()ident(path)operator(\))operator(.)ident(entries)operator(.)ident(grep)operator(()regexp<delimiter(/)char(\\.)content([ch]$)delimiter(/)modifier(i)>operator(\))
+
+ident(dir) operator(=) constant(Dir)operator(.)ident(new)operator(()ident(path)operator(\))
+ident(files) operator(=) ident(dir)operator(.)ident(entries)operator(.)ident(grep)operator(()regexp<delimiter(/)char(\\.)content([ch]$)delimiter(/)modifier(i)>operator(\))
+
+reserved(begin)
+ ident(d) operator(=) constant(Dir)operator(.)ident(open)operator(()ident(dir)operator(\))
+reserved(rescue) constant(Errno)operator(::)constant(ENOENT)
+ ident(raise) string<delimiter(")content(Couldn't open )inline<delimiter(#{)ident(dir)delimiter(})>content( for reading: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(end)
+
+ident(files) operator(=) operator([)operator(])
+ident(d)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ ident(puts) ident(file)
+ reserved(next) reserved(unless) ident(file) operator(=)operator(~) regexp<delimiter(/)char(\\.)content([ch]$)delimiter(/)modifier(i)>
+
+ ident(filename) operator(=) string<delimiter(")inline<delimiter(#{)ident(dir)delimiter(})>content(/)inline<delimiter(#{)ident(file)delimiter(})>delimiter(")>
+ comment(# There is no -T equivalent in Ruby, but we can still test emptiness)
+ ident(files)operator(.)ident(push)operator(()ident(filename)operator(\)) reserved(if) ident(test)operator(()integer(?s)operator(,) ident(filename)operator(\))
+reserved(end)
+
+ident(dirs)operator(.)ident(entries)operator(.)ident(grep)operator(()regexp<delimiter(/)content(^)char(\\d)content(+$)delimiter(/)>operator(\))operator(.)
+ ident(map) operator({) operator(|)ident(file)operator(|) operator([)ident(file)operator(,) string<delimiter(")inline<delimiter(#{)ident(path)delimiter(})>content(/)inline<delimiter(#{)ident(file)delimiter(})>delimiter(")>operator(])operator(}) operator(.)
+ ident(select) operator({) operator(|)ident(file)operator(|) ident(test)operator(()integer(?d)operator(,) ident(file)operator([)integer(1)operator(])operator(\)) operator(})operator(.)
+ ident(sort) operator({) operator(|)ident(a)operator(,)ident(b)operator(|) ident(a)operator([)integer(0)operator(]) operator(<=>) ident(b)operator([)integer(0)operator(]) operator(})operator(.)
+ ident(map) operator({) operator(|)ident(file)operator(|) ident(file)operator([)integer(1)operator(]) operator(})
+
+
+comment(# @@PLEAC@@_9.7)
+ident(require) string<delimiter(')content(find)delimiter(')>
+constant(Find)operator(.)ident(find)operator(()ident(dirlist)operator(\)) reserved(do) operator(|)ident(file)operator(|)
+ comment(# do whatever)
+reserved(end)
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) string<delimiter(%w{)content(.)delimiter(})> operator(:) pre_constant(ARGV)
+constant(Find)operator(.)ident(find)operator(()operator(*)ident(argv)operator(\)) reserved(do) operator(|)ident(file)operator(|)
+ ident(print) ident(file)operator(,) operator(()ident(test)operator(()integer(?d)operator(,) ident(file)operator(\)) operator(?) string<delimiter(")content(/)char(\\n)delimiter(")> operator(:) string<delimiter(")char(\\n)delimiter(")>operator(\))
+reserved(end)
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) string<delimiter(%w{)content(.)delimiter(})> operator(:) pre_constant(ARGV)
+ident(sum) operator(=) integer(0)
+constant(Find)operator(.)ident(find)operator(()operator(*)ident(argv)operator(\)) reserved(do) operator(|)ident(file)operator(|)
+ ident(size) operator(=) ident(test)operator(()integer(?s)operator(,) ident(file)operator(\)) operator(||) integer(0)
+ ident(sum) operator(+)operator(=) ident(size)
+reserved(end)
+ident(puts) string<delimiter(")inline<delimiter(#{)ident(argv)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>content( contains )inline<delimiter(#{)ident(sum)delimiter(})>content( bytes)delimiter(")>
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) string<delimiter(%w{)content(.)delimiter(})> operator(:) pre_constant(ARGV)
+ident(saved_size)operator(,) ident(saved_name) operator(=) operator(-)integer(1)operator(,) string<delimiter(")delimiter(")>
+constant(Find)operator(.)ident(find)operator(()operator(*)ident(argv)operator(\)) reserved(do) operator(|)ident(file)operator(|)
+ ident(size) operator(=) ident(test)operator(()integer(?s)operator(,) ident(file)operator(\)) operator(||) integer(0)
+ reserved(next) reserved(unless) ident(test)operator(()integer(?f)operator(,) ident(file)operator(\)) operator(&&) ident(size) operator(>) ident(saved_size)
+ ident(saved_size) operator(=) ident(size)
+ ident(saved_name) operator(=) ident(file)
+reserved(end)
+ident(puts) string<delimiter(")content(Biggest file )inline<delimiter(#{)ident(saved_name)delimiter(})>content( in )inline<delimiter(#{)ident(argv)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\))delimiter(})>content( is )inline<delimiter(#{)ident(saved_size)delimiter(})>delimiter(")>
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) string<delimiter(%w{)content(.)delimiter(})> operator(:) pre_constant(ARGV)
+ident(age)operator(,) ident(name) operator(=) pre_constant(nil)
+constant(Find)operator(.)ident(find)operator(()operator(*)ident(argv)operator(\)) reserved(do) operator(|)ident(file)operator(|)
+ ident(mtime) operator(=) constant(File)operator(.)ident(stat)operator(()ident(file)operator(\))operator(.)ident(mtime)
+ reserved(next) reserved(if) ident(age) operator(&&) ident(age) operator(>) ident(mtime)
+ ident(age) operator(=) ident(mtime)
+ ident(name) operator(=) ident(file)
+reserved(end)
+ident(puts) string<delimiter(")inline<delimiter(#{)ident(name)delimiter(})>content( )inline<delimiter(#{)ident(age)delimiter(})>delimiter(")>
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# fdirs - find all directories)
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) string<delimiter(%w{)content(.)delimiter(})> operator(:) pre_constant(ARGV)
+constant(File)operator(.)ident(find)operator(()operator(*)ident(argv)operator(\)) operator({) operator(|)ident(file)operator(|) ident(puts) ident(file) reserved(if) ident(test)operator(()integer(?d)operator(,) ident(file)operator(\)) operator(})
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_9.8)
+ident(require) string<delimiter(')content(fileutils)delimiter(')>
+
+ident(puts) string<delimiter(")content(Usage )inline<delimiter(#{)global_variable($0)delimiter(})>content( dir ...)delimiter(")> reserved(if) pre_constant(ARGV)operator(.)ident(empty?)
+pre_constant(ARGV)operator(.)ident(each) reserved(do) operator(|)ident(dir)operator(|)
+ constant(FileUtils)operator(.)ident(rmtree)operator(()ident(dir)operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.9)
+ident(require) string<delimiter(')content(ftools)delimiter(')>
+ident(names)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ ident(newname) operator(=) ident(file)
+ reserved(begin)
+ constant(File)operator(.)ident(move)operator(()ident(file)operator(,) ident(newname)operator(\))
+ reserved(rescue) constant(Errno)operator(::)constant(EPERM)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(Couldn't rename )inline<delimiter(#{)ident(file)delimiter(})>content( to )inline<delimiter(#{)ident(newname)delimiter(})>content(: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+ reserved(end)
+reserved(end)
+
+ident(require) string<delimiter(')content(ftools)delimiter(')>
+ident(op) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) operator(()ident(raise) string<delimiter(")content(Usage: rename expr [files])char(\\n)delimiter(")>operator(\)) operator(:) pre_constant(ARGV)operator(.)ident(shift)
+ident(argv) operator(=) pre_constant(ARGV)operator(.)ident(empty?) operator(?) global_variable($stdin)operator(.)ident(readlines)operator(.)ident(map) operator({) operator(|)ident(f)operator(|) ident(f)operator(.)ident(chomp) operator(}) operator(:) pre_constant(ARGV)
+ident(argv)operator(.)ident(each) reserved(do) operator(|)ident(file)operator(|)
+ ident(was) operator(=) ident(file)
+ ident(file) operator(=) ident(eval)operator(()string<delimiter(")content(file.)inline<delimiter(#{)ident(op)delimiter(})>delimiter(")>operator(\))
+ constant(File)operator(.)ident(move)operator(()ident(was)operator(,) ident(file)operator(\)) reserved(unless) ident(was) operator(==) ident(file)
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.10)
+ident(base) operator(=) constant(File)operator(.)ident(basename)operator(()ident(path)operator(\))
+ident(dir) operator(=) constant(File)operator(.)ident(dirname)operator(()ident(path)operator(\))
+comment(# ruby has no fileparse equivalent)
+ident(dir)operator(,) ident(base) operator(=) constant(File)operator(.)ident(split)operator(()ident(path)operator(\))
+ident(ext) operator(=) ident(base)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\.)content(.*$)delimiter(/)>operator(\))operator(.)ident(to_s)
+
+ident(path) operator(=) string<delimiter(')content(/usr/lib/libc.a)delimiter(')>
+ident(file) operator(=) constant(File)operator(.)ident(basename)operator(()ident(path)operator(\))
+ident(dir) operator(=) constant(File)operator(.)ident(dirname)operator(()ident(path)operator(\))
+
+ident(puts) string<delimiter(")content(dir is )inline<delimiter(#{)ident(dir)delimiter(})>content(, file is )inline<delimiter(#{)ident(file)delimiter(})>delimiter(")>
+comment(# dir is /usr/lib, file is libc.a)
+
+ident(path) operator(=) string<delimiter(')content(/usr/lib/libc.a)delimiter(')>
+ident(dir)operator(,) ident(filename) operator(=) constant(File)operator(.)ident(split)operator(()ident(path)operator(\))
+ident(name)operator(,) ident(ext) operator(=) ident(filename)operator(.)ident(split)operator(()regexp<delimiter(/)content((?=)char(\\.)content(\))delimiter(/)>operator(\))
+ident(puts) string<delimiter(")content(dir is )inline<delimiter(#{)ident(dir)delimiter(})>content(, name is )inline<delimiter(#{)ident(name)delimiter(})>content(, ext is )inline<delimiter(#{)ident(ext)delimiter(})>delimiter(")>
+comment(# NOTE: The Ruby code prints)
+comment(# dir is /usr/lib, name is libc, extension is .a)
+comment(# while the Perl code prints a '/' after the directory name)
+comment(# dir is /usr/lib/, name is libc, extension is .a)
+
+comment(# No fileparse_set_fstype(\) equivalent in ruby)
+
+reserved(def) method(extension)operator(()ident(path)operator(\))
+ ident(ext) operator(=) ident(path)operator(.)ident(scan)operator(()regexp<delimiter(/)char(\\.)content(.*$)delimiter(/)>operator(\))operator(.)ident(to_s)
+ ident(ext)operator(.)ident(sub)operator(()regexp<delimiter(/)content(^)char(\\.)delimiter(/)>operator(,) string<delimiter(")delimiter(")>operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.11)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# symirror - build spectral forest of symlinks)
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(require) string<delimiter(')content(fileutils)delimiter(')>
+
+ident(raise) string<delimiter(")content(usage: )inline<delimiter(#{)global_variable($0)delimiter(})>content( realdir mirrordir)delimiter(")> reserved(unless) pre_constant(ARGV)operator(.)ident(size) operator(==) integer(2)
+
+ident(srcdir)operator(,)ident(dstdir) operator(=) pre_constant(ARGV)
+ident(srcmode) operator(=) constant(File)operator(::)ident(stat)operator(()ident(srcdir)operator(\))operator(.)ident(mode)
+constant(Dir)operator(.)ident(mkdir)operator(()ident(dstdir)operator(,) ident(srcmode) operator(&) integer(07777)operator(\)) reserved(unless) ident(test)operator(()integer(?d)operator(,) ident(dstdir)operator(\))
+
+comment(# fix relative paths)
+constant(Dir)operator(.)ident(chdir)operator(()ident(srcdir)operator(\)) operator({)ident(srcdir) operator(=) constant(Dir)operator(.)ident(pwd)operator(})
+constant(Dir)operator(.)ident(chdir)operator(()ident(dstdir)operator(\)) operator({)ident(dstdir) operator(=) constant(Dir)operator(.)ident(pwd)operator(})
+
+constant(Find)operator(.)ident(find)operator(()ident(srcdir)operator(\)) reserved(do) operator(|)ident(srcfile)operator(|)
+ reserved(if) ident(test)operator(()integer(?d)operator(,) ident(srcfile)operator(\))
+ ident(dest) operator(=) ident(srcfile)operator(.)ident(sub)operator(()regexp<delimiter(/)content(^)inline<delimiter(#{)ident(srcdir)delimiter(})>delimiter(/)>operator(,) ident(dstdir)operator(\))
+ ident(dmode) operator(=) constant(File)operator(::)ident(stat)operator(()ident(srcfile)operator(\))operator(.)ident(mode) operator(&) integer(07777)
+ constant(Dir)operator(.)ident(mkdir)operator(()ident(dest)operator(,) ident(dmode)operator(\)) reserved(unless) ident(test)operator(()integer(?d)operator(,) ident(dest)operator(\))
+ ident(a) operator(=) constant(Dir)operator([)string<delimiter(")inline<delimiter(#{)ident(srcfile)delimiter(})>content(/*)delimiter(")>operator(])operator(.)ident(reject)operator({)operator(|)ident(f)operator(|) ident(test)operator(()integer(?d)operator(,) ident(f)operator(\))operator(})
+ constant(FileUtils)operator(.)ident(ln_s)operator(()ident(a)operator(,) ident(dest)operator(\))
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_9.12)
+comment(# we use the Getopt/Declare library here for convenience:)
+comment(# http://raa.ruby-lang.org/project/getoptdeclare/)
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby -w)
+comment(# lst - list sorted directory contents (depth first\))
+
+ident(require) string<delimiter(')content(find)delimiter(')>
+ident(require) string<delimiter(')content(etc)delimiter(')>
+ident(require) string<delimiter(")content(Getopt/Declare)delimiter(")>
+
+comment(# Note: in the option-spec below there must by at least one hard)
+comment(# tab in between each -option and its description. For example)
+comment(# -i <tab> read from stdin)
+
+ident(opts) operator(=) constant(Getopt)operator(::)constant(Declare)operator(.)ident(new)operator(()string<delimiter(<<'EOPARAM')>operator(\))string<content(
+ ============
+ Input Format:
+ -i read from stdin
+ ============
+ Output Format:
+ -l long listing
+ -r reverse listing
+ ============
+ Sort on: (one of\)
+ -m mtime (modify time - default\)
+ {$sort_criteria = :mtime}
+ -u atime (access time\)
+ {$sort_criteria = :atime}
+ -c ctime (inode change time\)
+ {$sort_criteria = :ctime}
+ -s size
+ {$sort_criteria = :size}
+ [mutex: -m -u -c -s]
+)delimiter(
+EOPARAM)>
+
+global_variable($sort_criteria) operator(||)operator(=) symbol(:mtime)
+ident(files) operator(=) operator({)operator(})
+constant(DIRS) operator(=) ident(opts)operator([)string<delimiter(')content(-i)delimiter(')>operator(]) operator(?) global_variable($stdin)operator(.)ident(readlines)operator(.)ident(map)operator({)operator(|)ident(f)operator(|)ident(f)operator(.)ident(chomp!)operator(}) operator(:) pre_constant(ARGV)
+constant(DIRS)operator(.)ident(each) reserved(do) operator(|)ident(dir)operator(|)
+ constant(Find)operator(.)ident(find)operator(()ident(dir)operator(\)) reserved(do) operator(|)ident(ent)operator(|)
+ ident(files)operator([)ident(ent)operator(]) operator(=) constant(File)operator(::)ident(stat)operator(()ident(ent)operator(\))
+ reserved(end)
+reserved(end)
+ident(entries) operator(=) ident(files)operator(.)ident(keys)operator(.)ident(sort_by)operator({)operator(|)ident(f)operator(|) ident(files)operator([)ident(f)operator(])operator(.)ident(send)operator(()global_variable($sort_criteria)operator(\))operator(})
+ident(entries) operator(=) ident(entries)operator(.)ident(reverse) reserved(unless) ident(opts)operator([)string<delimiter(')content(-r)delimiter(')>operator(])
+
+ident(entries)operator(.)ident(each) reserved(do) operator(|)ident(ent)operator(|)
+ reserved(unless) ident(opts)operator([)string<delimiter(')content(-l)delimiter(')>operator(])
+ ident(puts) ident(ent)
+ reserved(next)
+ reserved(end)
+ ident(stats) operator(=) ident(files)operator([)ident(ent)operator(])
+ ident(ftime) operator(=) ident(stats)operator(.)ident(send)operator(()global_variable($sort_criteria) operator(==) symbol(:size) operator(?) symbol(:mtime) operator(:) global_variable($sort_criteria)operator(\))
+ ident(printf) string<delimiter(")content(%6d %04o %6d %8s %8s %8d %s %s)char(\\n)delimiter(")>operator(,)
+ ident(stats)operator(.)ident(ino)operator(,)
+ ident(stats)operator(.)ident(mode) operator(&) integer(07777)operator(,)
+ ident(stats)operator(.)ident(nlink)operator(,)
+ constant(ETC)operator(::)constant(PASSWD)operator([)ident(stats)operator(.)ident(uid)operator(])operator(.)ident(name)operator(,)
+ constant(ETC)operator(::)constant(GROUP)operator([)ident(stats)operator(.)ident(gid)operator(])operator(.)ident(name)operator(,)
+ ident(stats)operator(.)ident(size)operator(,)
+ ident(ftime)operator(.)ident(strftime)operator(()string<delimiter(")content(%a %b %d %H:%M:%S %Y)delimiter(")>operator(\))operator(,)
+ ident(ent)
+reserved(end)
+
+
+comment(# @@PLEAC@@_10.0)
+reserved(def) method(hello)
+ global_variable($greeted) operator(+)operator(=) integer(1) comment(# in Ruby, a variable beginning with $ is global (can be any type of course\))
+ ident(puts) string<delimiter(")content(hi there!)delimiter(")>
+reserved(end)
+
+comment(# We need to initialize $greeted before it can be used, because "+=" is waiting a Numeric object)
+global_variable($greeted) operator(=) integer(0)
+ident(hello) comment(# note that appending (\) is optional to function calls with no parameters)
+
+
+comment(# @@PLEAC@@_10.1)
+comment(# In Ruby, parameters are named anyway)
+reserved(def) method(hypotenuse)operator(()ident(side1)operator(,) ident(side2)operator(\))
+ constant(Math)operator(.)ident(sqrt)operator(()ident(side1)operator(**)integer(2) operator(+) ident(side2)operator(**)integer(2)operator(\)) comment(# the sqrt function comes from the Math module)
+reserved(end)
+ident(diag) operator(=) ident(hypotenuse)operator(()integer(3)operator(,) integer(4)operator(\))
+
+ident(puts) ident(hypotenuse)operator(()integer(3)operator(,) integer(4)operator(\))
+
+ident(a) operator(=) operator([)integer(3)operator(,) integer(4)operator(])
+ident(print) ident(hypotenuse)operator(()operator(*)ident(a)operator(\)) comment(# the star operator will magically convert an Array into a "tuple")
+
+ident(both) operator(=) ident(men) operator(+) ident(women)
+
+comment(# In Ruby, all objects are references, so the same problem arises; we then return a new object)
+ident(nums) operator(=) operator([)float(1.4)operator(,) float(3.5)operator(,) float(6.7)operator(])
+reserved(def) method(int_all)operator(()ident(n)operator(\))
+ ident(n)operator(.)ident(collect) operator({) operator(|)ident(v)operator(|) ident(v)operator(.)ident(to_i) operator(})
+reserved(end)
+ident(ints) operator(=) ident(int_all)operator(()ident(nums)operator(\))
+
+ident(nums) operator(=) operator([)float(1.4)operator(,) float(3.5)operator(,) float(6.7)operator(])
+reserved(def) method(trunc_em)operator(()ident(n)operator(\))
+ ident(n)operator(.)ident(collect!) operator({) operator(|)ident(v)operator(|) ident(v)operator(.)ident(to_i) operator(}) comment(# the bang-version of collect modifies the object)
+reserved(end)
+ident(trunc_em)operator(()ident(nums)operator(\))
+
+comment(# Ruby has two chomp version:)
+comment(# ``chomp'' chomps the record separator and returns what's expected)
+comment(# ``chomp!'' does the same but also modifies the parameter object)
+
+
+comment(# @@PLEAC@@_10.2)
+reserved(def) method(somefunc)
+ ident(variable) operator(=) ident(something) comment(# variable is local by default)
+reserved(end)
+
+ident(name)operator(,) ident(age) operator(=) pre_constant(ARGV)
+ident(start) operator(=) ident(fetch_time)
+
+ident(a)operator(,) ident(b) operator(=) ident(pair) comment(# will succeed if pair is an Array object (like ARGV is\))
+ident(c) operator(=) ident(fetch_time)
+
+comment(# In ruby, run_check can't access a, b, or c until they are)
+comment(# explicitely defined global (using leading $\), even if they are)
+comment(# both defined in the same scope)
+
+reserved(def) method(check_x)operator(()ident(x)operator(\))
+ ident(y) operator(=) string<delimiter(")content(whatever)delimiter(")>
+ ident(run_check)
+ reserved(if) global_variable($condition)
+ ident(puts) string<delimiter(")content(got $x)delimiter(")>
+ reserved(end)
+reserved(end)
+
+comment(# The following will keep a reference to the array, though the)
+comment(# results will be slightly different from perl: the last element)
+comment(# of $global_array will be itself an array)
+reserved(def) method(save_array)operator(()ident(ary)operator(\))
+ global_variable($global_array) operator(<<) ident(ary)
+reserved(end)
+
+comment(# The following gives the same results as in Perl for $global_array,)
+comment(# though it doesn't illustrate anymore the way to keep a reference)
+comment(# to an object: $global_array is extended with the elements of ary)
+reserved(def) method(save_array)operator(()ident(ary)operator(\))
+ global_variable($global_array) operator(+)operator(=) ident(ary)
+reserved(end)
+
+
+comment(# @@PLEAC@@_10.3)
+comment(# In Ruby, AFAIK a method cannot access "local variables" defined)
+comment(# upper scope; mostly because everything is an object, so you'll)
+comment(# do the same by defining an attribute or a static attribute)
+
+comment(# In Ruby the BEGIN also exists:)
+reserved(BEGIN) operator({) ident(puts) string<delimiter(")content(hello from BEGIN)delimiter(")> operator(})
+ident(puts) string<delimiter(")content(hello from main)delimiter(")>
+reserved(BEGIN) operator({) ident(puts) string<delimiter(")content(hello from 2nd BEGIN)delimiter(")> operator(})
+comment(# gives:)
+comment(# hello from BEGIN)
+comment(# hello from 2nd BEGIN)
+comment(# hello from main)
+
+comment(# In Ruby, it can be written as a static method and a static)
+comment(# variable)
+reserved(class) class(Counter)
+ class_variable(@@counter) operator(=) integer(0)
+ reserved(def) constant(Counter)operator(.)ident(next_counter)operator(;) class_variable(@@counter) operator(+)operator(=) integer(1)operator(;) reserved(end)
+reserved(end)
+
+comment(# There is no need of BEGIN since the variable will get)
+comment(# initialized when parsing)
+reserved(class) class(Counter)
+ class_variable(@@counter) operator(=) integer(42)
+ reserved(def) constant(Counter)operator(.)ident(next_counter)operator(;) class_variable(@@counter) operator(+)operator(=) integer(1)operator(;) reserved(end)
+ reserved(def) constant(Counter)operator(.)ident(prev_counter)operator(;) class_variable(@@counter) operator(-)operator(=) integer(1)operator(;) reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_10.4)
+comment(# You can either get the whole trace as an array of strings, each)
+comment(# string telling which file, line and method is calling:)
+ident(caller)
+
+comment(# ...or only the last caller)
+ident(caller)operator([)integer(0)operator(])
+
+comment(# We need to extract just the method name of the backtrace:)
+reserved(def) method(whoami)operator(;) ident(caller)operator(()operator(\))operator([)integer(0)operator(]) operator(=)operator(~) regexp<delimiter(/)content(in `([^']+\)')delimiter(/)> operator(?) global_variable($1) operator(:) string<delimiter(')content((anonymous\))delimiter(')>operator(;) reserved(end)
+reserved(def) method(whowasi)operator(;) ident(caller)operator(()operator(\))operator([)integer(1)operator(]) operator(=)operator(~) regexp<delimiter(/)content(in `([^']+\)')delimiter(/)> operator(?) global_variable($1) operator(:) string<delimiter(')content((anonymous\))delimiter(')>operator(;) reserved(end)
+
+
+comment(# @@PLEAC@@_10.5)
+comment(# In Ruby, every value is a reference on an object, thus there is)
+comment(# no such problem)
+ident(array_diff)operator(()ident(array1)operator(,) ident(array2)operator(\))
+
+reserved(def) method(add_vecpair)operator(()ident(a1)operator(,) ident(a2)operator(\))
+ ident(results) operator(=) operator([)operator(])
+ ident(a1)operator(.)ident(each_index) operator({) operator(|)ident(i)operator(|) ident(results) operator(<<) operator(()ident(a1)operator([)ident(i)operator(]) operator(+) ident(a2)operator([)ident(i)operator(])operator(\)) operator(})
+ ident(results)
+reserved(end)
+ident(a) operator(=) operator([)integer(1)operator(,) integer(2)operator(])
+ident(b) operator(=) operator([)integer(5)operator(,) integer(8)operator(])
+ident(c) operator(=) ident(add_vecpair)operator(()ident(a)operator(,) ident(b)operator(\))
+ident(p) ident(c)
+
+comment(# Add this to the beginning of the function to check if we were)
+comment(# given two arrays)
+ident(a1)operator(.)ident(type) operator(==) constant(Array) operator(&&) ident(a2)operator(.)ident(type) operator(==) constant(Array) reserved(or)
+ ident(raise) string<delimiter(")content(usage: add_vecpair array1 array2 (was used with: )inline<delimiter(#{)ident(a1)operator(.)ident(type)delimiter(})>content( )inline<delimiter(#{)ident(a2)operator(.)ident(type)delimiter(})>content(\))delimiter(")>
+
+
+comment(# @@PLEAC@@_10.6)
+comment(# There is no return context in Ruby)
+
+
+comment(# @@PLEAC@@_10.7)
+comment(# Like in Perl, we need to fake with a hash, but it's dirty :-()
+reserved(def) method(thefunc)operator(()ident(param_args)operator(\))
+ ident(args) operator(=) operator({) string<delimiter(')content(INCREMENT)delimiter(')> operator(=)operator(>) string<delimiter(')content(10s)delimiter(')>operator(,) string<delimiter(')content(FINISH)delimiter(')> operator(=)operator(>) string<delimiter(')content(0)delimiter(')>operator(,) string<delimiter(')content(START)delimiter(')> operator(=)operator(>) integer(0) operator(})
+ ident(args)operator(.)ident(update)operator(()ident(param_args)operator(\))
+ reserved(if) operator(()ident(args)operator([)string<delimiter(')content(INCREMENT)delimiter(')>operator(]) operator(=)operator(~) regexp<delimiter(/)content(m$)delimiter(/)> operator(\))
+ comment(# .....)
+ reserved(end)
+reserved(end)
+
+ident(thefunc)operator(()operator({) string<delimiter(')content(INCREMENT)delimiter(')> operator(=)operator(>) string<delimiter(')content(20s)delimiter(')>operator(,) string<delimiter(')content(START)delimiter(')> operator(=)operator(>) string<delimiter(')content(+5m)delimiter(')>operator(,) string<delimiter(')content(FINISH)delimiter(')> operator(=)operator(>) string<delimiter(')content(+30m)delimiter(')> operator(})operator(\))
+ident(thefunc)operator(()operator({)operator(})operator(\))
+
+
+comment(# @@PLEAC@@_10.8)
+comment(# there is no "undef" direct equivalent but there is the slice equiv:)
+ident(a)operator(,) ident(c) operator(=) ident(func)operator(.)ident(indexes)operator(()integer(0)operator(,) integer(2)operator(\))
+
+
+comment(# @@PLEAC@@_10.9)
+comment(# Ruby has no such limitation:)
+reserved(def) method(somefunc)
+ ident(ary) operator(=) operator([)operator(])
+ ident(hash) operator(=) operator({)operator(})
+ comment(# ...)
+ reserved(return) ident(ary)operator(,) ident(hash)
+reserved(end)
+ident(arr)operator(,) ident(dict) operator(=) ident(somefunc)
+
+ident(array_of_hashes) operator(=) ident(fn)
+ident(h1)operator(,) ident(h2)operator(,) ident(h3) operator(=) ident(fn)
+
+
+comment(# @@PLEAC@@_10.10)
+reserved(return)
+comment(# or (equivalent\))
+reserved(return) pre_constant(nil)
+
+
+comment(# @@PLEAC@@_10.11)
+comment(# You can't prototype in Ruby regarding types :-()
+comment(# Though, you can force the number of arguments:)
+reserved(def) method(func_with_no_arg)operator(;) reserved(end)
+reserved(def) method(func_with_no_arg)operator(()operator(\))operator(;) reserved(end)
+reserved(def) method(func_with_one_arg)operator(()ident(a1)operator(\))operator(;) reserved(end)
+reserved(def) method(func_with_two_args)operator(()ident(a1)operator(,) ident(a2)operator(\))operator(;) reserved(end)
+reserved(def) method(func_with_any_number_of_args)operator(()operator(*)ident(args)operator(\))operator(;) reserved(end)
+
+
+comment(# @@PLEAC@@_10.12)
+ident(raise) string<delimiter(")content(some message)delimiter(")> comment(# raise exception)
+
+reserved(begin)
+ ident(val) operator(=) ident(func)
+reserved(rescue) constant(Exception) operator(=)operator(>) ident(msg)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(func raised an exception: )inline<delimiter(#{)ident(msg)delimiter(})>delimiter(")>
+reserved(end)
+
+comment(# In Ruby the rescue statement uses an exception class, every)
+comment(# exception which is not matched is still continuing)
+reserved(begin)
+ ident(val) operator(=) ident(func)
+reserved(rescue) constant(FullMoonError)
+ operator(...)
+reserved(end)
+
+
+comment(# @@PLEAC@@_10.13)
+comment(# Saving Global Values)
+comment(# Of course we can just save the value and restore it later:)
+reserved(def) method(print_age)
+ ident(puts) string<delimiter(")content(Age is )inline<delimiter(#{)global_variable($age)delimiter(})>delimiter(")>
+reserved(end)
+
+global_variable($age) operator(=) integer(18) comment(# global variable)
+ident(print_age)operator(()operator(\))
+reserved(if) ident(condition)
+ ident(safeage) operator(=) global_variable($age)
+ global_variable($age) operator(=) integer(23)
+ ident(print_age)operator(()operator(\))
+ global_variable($age) operator(=) ident(safeage)
+reserved(end)
+
+comment(# We can also use a method that saves the global variable and)
+comment(# restores it automatically when the block is left:)
+
+reserved(def) method(local)operator(()ident(var)operator(\))
+ ident(eval)operator(()string<delimiter(")content(save = )inline<delimiter(#{)ident(var)operator(.)ident(id2name)delimiter(})>delimiter(")>operator(\))
+ reserved(begin)
+ ident(result) operator(=) reserved(yield)
+ reserved(ensure)
+ comment(# we want to call this even if we got an exception)
+ ident(eval)operator(()string<delimiter(")inline<delimiter(#{)ident(var)operator(.)ident(id2name)delimiter(})>content( = save)delimiter(")>operator(\))
+ reserved(end)
+ ident(result)
+reserved(end)
+
+ident(condition) operator(=) pre_constant(true)
+global_variable($age) operator(=) integer(18)
+ident(print_age)operator(()operator(\))
+reserved(if) ident(condition)
+ ident(local)operator(()symbol(:$age)operator(\)) operator({)
+ global_variable($age) operator(=) integer(23)
+ ident(print_age)operator(()operator(\))
+ operator(})
+reserved(end)
+ident(print_age)operator(()operator(\))
+
+comment(# There is no need to use local(\) for filehandles or directory)
+comment(# handles in ruby because filehandles are normal objects.)
+
+
+comment(# @@PLEAC@@_10.14)
+comment(# In Ruby you may redefine a method [but not overload it :-(])
+comment(# just by defining again with the same name.)
+reserved(def) method(foo)operator(;) ident(puts) string<delimiter(')content(foo)delimiter(')>operator(;) reserved(end)
+reserved(def) method(foo)operator(;) ident(puts) string<delimiter(')content(bar)delimiter(')>operator(;) reserved(end)
+ident(foo)
+comment(#=> bar)
+
+comment(# You can also take a reference to an existing method before)
+comment(# redefining a new one, using the `alias' keyword)
+reserved(def) method(foo)operator(;) ident(puts) string<delimiter(')content(foo)delimiter(')>operator(;) reserved(end)
+reserved(alias) ident(foo_orig) ident(foo)
+reserved(def) method(foo)operator(;) ident(puts) string<delimiter(')content(bar)delimiter(')>operator(;) reserved(end)
+ident(foo_orig)
+ident(foo)
+comment(#=> foo)
+comment(#=> bar)
+
+comment(# AFAIK, there is no direct way to create a new method whose name)
+comment(# comes from a variable, so use "eval")
+ident(colors) operator(=) string<delimiter(%w()content(red blue green yellow orange purple violet)delimiter(\))>
+ident(colors)operator(.)ident(each) operator({) operator(|)ident(c)operator(|)
+ ident(eval) string<delimiter(<<-EOS)>string<content(
+ def )inline<delimiter(#{)ident(c)delimiter(})>content((*a\)
+ "<FONT COLOR=')inline<delimiter(#{)ident(c)delimiter(})>content('>" + a.to_s + "</FONT>"
+ end)delimiter(
+ EOS)>
+operator(})
+
+
+comment(# @@PLEAC@@_10.15)
+reserved(def) method(method_missing)operator(()ident(name)operator(,) operator(*)ident(args)operator(\))
+ string<delimiter(")content(<FONT COLOR=')inline<delimiter(#{)ident(name)delimiter(})>content('>)delimiter(")> operator(+) ident(args)operator(.)ident(join)operator(()string<delimiter(')content( )delimiter(')>operator(\)) operator(+) string<delimiter(")content(</FONT>)delimiter(")>
+reserved(end)
+ident(puts) ident(chartreuse)operator(()string<delimiter(")content(stuff)delimiter(")>operator(\))
+
+
+comment(# @@PLEAC@@_10.16)
+reserved(def) method(outer)operator(()ident(arg)operator(\))
+ ident(x) operator(=) ident(arg) operator(+) integer(35)
+ ident(inner) operator(=) ident(proc) operator({) ident(x) operator(*) integer(19) operator(})
+ ident(x) operator(+) ident(inner)operator(.)ident(call)operator(()operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_10.17)
+comment(#!/usr/bin/ruby -w)
+comment(# mailsort - sort mbox by different criteria)
+ident(require) string<delimiter(')content(English)delimiter(')>
+ident(require) string<delimiter(')content(Date)delimiter(')>
+
+comment(# Objects of class Mail represent a single mail.)
+reserved(class) class(Mail)
+ ident(attr_accessor) symbol(:no)
+ ident(attr_accessor) symbol(:subject)
+ ident(attr_accessor) symbol(:fulltext)
+ ident(attr_accessor) symbol(:date)
+
+ reserved(def) method(initialize)
+ instance_variable(@fulltext) operator(=) string<delimiter(")delimiter(")>
+ instance_variable(@subject) operator(=) string<delimiter(")delimiter(")>
+ reserved(end)
+
+ reserved(def) method(append)operator(()ident(para)operator(\))
+ instance_variable(@fulltext) operator(<<) ident(para)
+ reserved(end)
+
+ comment(# this is called if you call puts(mail\))
+ reserved(def) method(to_s)
+ instance_variable(@fulltext)
+ reserved(end)
+reserved(end)
+
+comment(# represents a list of mails.)
+reserved(class) class(Mailbox) operator(<) constant(Array)
+
+ constant(Subjectpattern) operator(=) constant(Regexp)operator(.)ident(new)operator(()string<delimiter(')content(Subject:)content(\\s)content(*(?:Re:)content(\\s)content(*\)*(.*\))content(\\n)delimiter(')>operator(\))
+ constant(Datepattern) operator(=) constant(Regexp)operator(.)ident(new)operator(()string<delimiter(')content(Date:)content(\\s)content(*(.*\))content(\\n)delimiter(')>operator(\))
+
+ comment(# reads mails from open file and stores them)
+ reserved(def) method(read)operator(()ident(file)operator(\))
+ global_variable($INPUT_RECORD_SEPARATOR) operator(=) string<delimiter(')delimiter(')> comment(# paragraph reads)
+ ident(msgno) operator(=) operator(-)integer(1)
+ ident(file)operator(.)ident(each) operator({) operator(|)ident(para)operator(|)
+ reserved(if) ident(para) operator(=)operator(~) regexp<delimiter(/)content(^From)delimiter(/)>
+ ident(mail) operator(=) constant(Mail)operator(.)ident(new)
+ ident(mail)operator(.)ident(no) operator(=) operator(()ident(msgno) operator(+)operator(=) integer(1)operator(\))
+ ident(md) operator(=) constant(Subjectpattern)operator(.)ident(match)operator(()ident(para)operator(\))
+ reserved(if) ident(md)
+ ident(mail)operator(.)ident(subject) operator(=) ident(md)operator([)integer(1)operator(])
+ reserved(end)
+ ident(md) operator(=) constant(Datepattern)operator(.)ident(match)operator(()ident(para)operator(\))
+ reserved(if) ident(md)
+ ident(mail)operator(.)ident(date) operator(=) constant(DateTime)operator(.)ident(parse)operator(()ident(md)operator([)integer(1)operator(])operator(\))
+ reserved(else)
+ ident(mail)operator(.)ident(date) operator(=) constant(DateTime)operator(.)ident(now)
+ reserved(end)
+ pre_constant(self)operator(.)ident(push)operator(()ident(mail)operator(\))
+ reserved(end)
+ ident(mail)operator(.)ident(append)operator(()ident(para)operator(\)) reserved(if) ident(mail)
+ operator(})
+ reserved(end)
+
+ reserved(def) method(sort_by_subject_and_no)
+ pre_constant(self)operator(.)ident(sort_by) operator({) operator(|)ident(m)operator(|)
+ operator([)ident(m)operator(.)ident(subject)operator(,) ident(m)operator(.)ident(no)operator(])
+ operator(})
+ reserved(end)
+
+ comment(# sorts by a list of attributs of mail, given as symbols)
+ reserved(def) method(sort_by_attributs)operator(()operator(*)ident(attrs)operator(\))
+ comment(# you can sort an Enumerable by an array of)
+ comment(# values, they would be compared)
+ comment(# from ary[0] to ary[n]t, say:)
+ comment(# ['b',1] > ['a',10] > ['a',9])
+ pre_constant(self)operator(.)ident(sort_by) operator({) operator(|)ident(elem)operator(|)
+ ident(attrs)operator(.)ident(map) operator({) operator(|)ident(attr)operator(|)
+ ident(elem)operator(.)ident(send)operator(()ident(attr)operator(\))
+ operator(})
+ operator(})
+ reserved(end)
+
+reserved(end)
+
+ident(mailbox) operator(=) constant(Mailbox)operator(.)ident(new)
+ident(mailbox)operator(.)ident(read)operator(()pre_constant(ARGF)operator(\))
+
+comment(# print only subjects sorted by subject and number)
+reserved(for) ident(m) reserved(in) ident(mailbox)operator(.)ident(sort_by_subject_and_no)
+ ident(puts)operator(()ident(m)operator(.)ident(subject)operator(\))
+reserved(end)
+
+comment(# print complete mails sorted by date, then subject, then number)
+reserved(for) ident(m) reserved(in) ident(mailbox)operator(.)ident(sort_by_attributs)operator(()symbol(:date)operator(,) symbol(:subject)operator(\))
+ ident(puts)operator(()ident(m)operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_11.7)
+reserved(def) method(mkcounter)operator(()ident(count)operator(\))
+ ident(start) operator(=) ident(count)
+ ident(bundle) operator(=) operator({)
+ string<delimiter(")content(NEXT)delimiter(")> operator(=)operator(>) ident(proc) operator({) ident(count) operator(+)operator(=) integer(1) operator(})operator(,)
+ string<delimiter(")content(PREV)delimiter(")> operator(=)operator(>) ident(proc) operator({) ident(count) operator(-)operator(=) integer(1) operator(})operator(,)
+ string<delimiter(")content(RESET)delimiter(")> operator(=)operator(>) ident(proc) operator({) ident(count) operator(=) ident(start) operator(})
+ operator(})
+ ident(bundle)operator([)string<delimiter(")content(LAST)delimiter(")>operator(]) operator(=) ident(bundle)operator([)string<delimiter(")content(PREV)delimiter(")>operator(])
+ reserved(return) ident(bundle)
+reserved(end)
+
+ident(c1) operator(=) ident(mkcounter)operator(()integer(20)operator(\))
+ident(c2) operator(=) ident(mkcounter)operator(()integer(77)operator(\))
+
+ident(puts) string<delimiter(")content(next c1: )inline<delimiter(#{)ident(c1)operator([)string<delimiter(")content(NEXT)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 21 )
+ident(puts) string<delimiter(")content(next c2: )inline<delimiter(#{)ident(c2)operator([)string<delimiter(")content(NEXT)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 78 )
+ident(puts) string<delimiter(")content(next c1: )inline<delimiter(#{)ident(c1)operator([)string<delimiter(")content(NEXT)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 22 )
+ident(puts) string<delimiter(")content(last c1: )inline<delimiter(#{)ident(c1)operator([)string<delimiter(")content(PREV)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 21 )
+ident(puts) string<delimiter(")content(last c1: )inline<delimiter(#{)ident(c1)operator([)string<delimiter(")content(LAST)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 20 )
+ident(puts) string<delimiter(")content(old c2: )inline<delimiter(#{)ident(c2)operator([)string<delimiter(")content(RESET)delimiter(")>operator(])operator(.)ident(call)delimiter(})>delimiter(")> comment(# 77 )
+
+
+comment(# @@PLEAC@@_11.15)
+reserved(class) class(Binary_tree)
+ reserved(def) method(initialize)operator(()ident(val)operator(\))
+ instance_variable(@value) operator(=) ident(val)
+ instance_variable(@left) operator(=) pre_constant(nil)
+ instance_variable(@right) operator(=) pre_constant(nil)
+ reserved(end)
+
+ comment(# insert given value into proper point of)
+ comment(# provided tree. If no tree provided, )
+ comment(# use implicit pass by reference aspect of @_)
+ comment(# to fill one in for our caller.)
+ reserved(def) method(insert)operator(()ident(val)operator(\))
+ reserved(if) ident(val) operator(<) instance_variable(@value) reserved(then)
+ reserved(if) instance_variable(@left) reserved(then)
+ instance_variable(@left)operator(.)ident(insert)operator(()ident(val)operator(\))
+ reserved(else)
+ instance_variable(@left) operator(=) constant(Binary_tree)operator(.)ident(new)operator(()ident(val)operator(\))
+ reserved(end)
+ reserved(elsif) ident(val) operator(>) instance_variable(@value) reserved(then)
+ reserved(if) instance_variable(@right) reserved(then)
+ instance_variable(@right)operator(.)ident(insert)operator(()ident(val)operator(\))
+ reserved(else)
+ instance_variable(@right) operator(=) constant(Binary_tree)operator(.)ident(new)operator(()ident(val)operator(\))
+ reserved(end)
+ reserved(else)
+ ident(puts) string<delimiter(")content(double)delimiter(")>
+ comment(# do nothing, no double values)
+ reserved(end)
+ reserved(end)
+
+ comment(# recurse on left child, )
+ comment(# then show current value, )
+ comment(# then recurse on right child. )
+ reserved(def) method(in_order)
+ instance_variable(@left)operator(.)ident(in_order) reserved(if) instance_variable(@left)
+ ident(print) instance_variable(@value)operator(,) string<delimiter(")content( )delimiter(")>
+ instance_variable(@right)operator(.)ident(in_order) reserved(if) instance_variable(@right)
+ reserved(end)
+
+ comment(# show current value, )
+ comment(# then recurse on left child, )
+ comment(# then recurse on right child.)
+ reserved(def) method(pre_order)
+ ident(print) instance_variable(@value)operator(,) string<delimiter(")content( )delimiter(")>
+ instance_variable(@left)operator(.)ident(pre_order) reserved(if) instance_variable(@left)
+ instance_variable(@right)operator(.)ident(pre_order) reserved(if) instance_variable(@right)
+ reserved(end)
+
+ comment(# recurse on left child, )
+ comment(# then recurse on right child,)
+ comment(# then show current value.)
+ reserved(def) method(post_order)
+ instance_variable(@left)operator(.)ident(post_order) reserved(if) instance_variable(@left)
+ instance_variable(@right)operator(.)ident(post_order) reserved(if) instance_variable(@right)
+ ident(print) instance_variable(@value)operator(,) string<delimiter(")content( )delimiter(")>
+ reserved(end)
+
+ comment(# find out whether provided value is in the tree.)
+ comment(# if so, return the node at which the value was found.)
+ comment(# cut down search time by only looking in the correct)
+ comment(# branch, based on current value.)
+ reserved(def) method(search)operator(()ident(val)operator(\))
+ reserved(if) ident(val) operator(==) instance_variable(@value) reserved(then)
+ reserved(return) pre_constant(self)
+ reserved(elsif) ident(val) operator(<) instance_variable(@value) reserved(then)
+ reserved(return) instance_variable(@left)operator(.)ident(search)operator(()ident(val)operator(\)) reserved(if) instance_variable(@left)
+ reserved(return) pre_constant(nil)
+ reserved(else)
+ reserved(return) instance_variable(@right)operator(.)ident(search)operator(()ident(val)operator(\)) reserved(if) instance_variable(@right)
+ reserved(return) pre_constant(nil)
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+comment(# first generate 20 random inserts)
+ident(test) operator(=) constant(Binary_tree)operator(.)ident(new)operator(()integer(0)operator(\))
+reserved(for) ident(a) reserved(in) integer(0)operator(..)integer(20)
+ ident(test)operator(.)ident(insert)operator(()ident(rand)operator(()integer(1000)operator(\))operator(\))
+reserved(end)
+
+comment(# now dump out the tree all three ways)
+ident(print) string<delimiter(")content(Pre order: )delimiter(")>operator(;) ident(test)operator(.)ident(pre_order)operator(;) ident(puts) string<delimiter(")delimiter(")>
+ident(print) string<delimiter(")content(In order: )delimiter(")>operator(;) ident(test)operator(.)ident(in_order)operator(;) ident(puts) string<delimiter(")delimiter(")>
+ident(print) string<delimiter(")content(Post order: )delimiter(")>operator(;) ident(test)operator(.)ident(post_order)operator(;) ident(puts) string<delimiter(")delimiter(")>
+
+ident(print) string<delimiter(")content(search?)delimiter(")>
+reserved(while) ident(gets)
+ ident(print) ident(test)operator(.)ident(search)operator(()global_variable($_)operator(.)ident(to_i)operator(\))
+ ident(print) string<delimiter(")char(\\n)content(search?)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_12.0)
+comment(# class and module names need to have the first letter capitalized)
+reserved(module) class(Alpha)
+ constant(NAME) operator(=) string<delimiter(')content(first)delimiter(')>
+reserved(end)
+reserved(module) class(Omega)
+ constant(NAME) operator(=) string<delimiter(')content(last)delimiter(')>
+reserved(end)
+ident(puts) string<delimiter(")content(Alpha is )inline<delimiter(#{)constant(Alpha)operator(::)constant(NAME)delimiter(})>content(, Omega is )inline<delimiter(#{)constant(Omega)operator(::)constant(NAME)delimiter(})>delimiter(")>
+
+comment(# ruby doesn't differentiate beteen compile-time and run-time)
+ident(require) string<delimiter(')content(getoptlong.rb)delimiter(')>
+ident(require) string<delimiter(')content(getoptlong)delimiter(')> comment(# assumes the .rb)
+ident(require) string<delimiter(')content(cards/poker.rb)delimiter(')>
+ident(require) string<delimiter(')content(cards/poker)delimiter(')> comment(# assumes the .rb)
+ident(load) string<delimiter(')content(cards/poker)delimiter(')> comment(# require only loads the file once)
+
+reserved(module) class(Cards)
+ reserved(module) class(Poker)
+ instance_variable(@card_deck) operator(=) constant(Array)operator(.)ident(new) comment(# or @card_deck = [])
+ reserved(def) method(shuffle)
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_12.1)
+comment(# a module exports all of its functions)
+reserved(module) class(Your_Module)
+ reserved(def) pre_constant(self)operator(.)ident(function)
+ comment(# this would be called as Your_Module.function)
+ reserved(end)
+
+ reserved(def) constant(Your_Module)operator(.)ident(another)
+ comment(# this is the same as above, but more specific)
+ reserved(end)
+reserved(end)
+
+comment(# @@PLEAC@@_12.2)
+reserved(begin)
+ ident(require) string<delimiter(')content(nonexistent)delimiter(')>
+reserved(rescue) constant(LoadError)
+ ident(puts) string<delimiter(")content(Couldn't load )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")> comment(# $! contains the last error string)
+reserved(end)
+
+comment(# @@PLEAC@@_12.4)
+comment(# module variables are private unless access functions are defined)
+reserved(module) class(Alpha)
+ instance_variable(@aa) operator(=) integer(10)
+ instance_variable(@bb) operator(=) integer(11)
+
+ reserved(def) pre_constant(self)operator(.)ident(put_aa)
+ ident(puts) instance_variable(@aa)
+ reserved(end)
+
+ reserved(def) pre_constant(self)operator(.)ident(bb)operator(=)operator(()ident(val)operator(\))
+ instance_variable(@bb) operator(=) ident(val)
+ reserved(end)
+reserved(end)
+
+constant(Alpha)operator(.)ident(bb) operator(=) integer(12)
+comment(# Alpha.aa = 10 # error, no aa=method)
+
+
+comment(# @@PLEAC@@_12.5)
+comment(# caller provides a backtrace of the call stack)
+reserved(module) class(MyModule)
+ reserved(def) method(find_caller)
+ ident(caller)
+ reserved(end)
+
+ reserved(def) method(find_caller2)operator(()ident(i)operator(\))
+ ident(caller)operator(()ident(i)operator(\)) comment(# an argument limits the size of the stack returned)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_12.6)
+reserved(BEGIN) operator({)
+ global_variable($logfile) operator(=) string<delimiter(')content(/tmp/mylog)delimiter(')> reserved(unless) reserved(defined?) global_variable($logfile)
+ global_variable($LF) operator(=) constant(File)operator(.)ident(open)operator(()global_variable($logfile)operator(,) string<delimiter(')content(a)delimiter(')>operator(\))
+operator(})
+
+reserved(module) class(Logger)
+ reserved(def) pre_constant(self)operator(.)ident(logmsg)operator(()ident(msg)operator(\))
+ global_variable($LF)operator(.)ident(puts) ident(msg)
+ reserved(end)
+
+ ident(logmsg)operator(()string<delimiter(')content(startup)delimiter(')>operator(\))
+reserved(end)
+
+reserved(END) operator({)
+ constant(Logger)operator(::)ident(logmsg)operator(()string<delimiter(')content(shutdown)delimiter(')>operator(\))
+ global_variable($LF)operator(.)ident(close)
+operator(})
+
+
+comment(# @@PLEAC@@_12.7)
+comment(#-----------------------------)
+comment(# results may be different on your system)
+comment(# % ruby -e "$LOAD_PATH.each_index { |i| printf("%d %s\\n", i, $LOAD_PATH[i] })
+comment(#0 /usr/local/lib/site_ruby/1.6)
+comment(#1 /usr/local/lib/site_ruby/1.6/i386-linux)
+comment(#2 /usr/local/lib/site_ruby/)
+comment(#3 /usr/lib/ruby/1.6)
+comment(#4 /usr/lib/ruby/1.6/i136-linux)
+comment(#5 .)
+comment(#-----------------------------)
+comment(# syntax for sh, bash, ksh, or zsh)
+comment(#$ export RUBYLIB=$HOME/rubylib)
+
+comment(# syntax for csh or tcsh)
+comment(# % setenv RUBYLIB ~/rubylib)
+comment(#-----------------------------)
+global_variable($LOAD_PATH)operator(.)ident(unshift) string<delimiter(")content(/projects/spectre/lib)delimiter(")>operator(;)
+
+
+comment(# @@PLEAC@@_12.8)
+comment(# equivalents in ruby are mkmf, SWIG, or Ruby/DL depending on usage)
+
+
+comment(# @@PLEAC@@_12.9)
+comment(# no equivalent in ruby)
+
+
+comment(# @@PLEAC@@_12.10)
+comment(# no equivalent in ruby)
+
+
+comment(# @@PLEAC@@_12.11)
+reserved(module) class(FineTime)
+ reserved(def) pre_constant(self)operator(.)ident(time)
+ comment(# to be defined later)
+ reserved(end)
+reserved(end)
+
+
+reserved(module) class(FineTime)
+ reserved(def) pre_constant(self)operator(.)ident(time)
+ string<delimiter(")content(its a fine time)delimiter(")>
+ reserved(end)
+reserved(end)
+
+ident(puts) constant(FineTime)operator(.)ident(time) comment(#=> "its a fine time")
+
+
+comment(# @@PLEAC@@_12.12)
+reserved(def) method(even_only)operator(()ident(n)operator(\))
+ ident(raise) string<delimiter(")inline<delimiter(#{)ident(n)delimiter(})>content( is not even)delimiter(")> reserved(if) operator(()ident(n) operator(&) integer(1)operator(\)) operator(!)operator(=) integer(0) comment(# one way to test)
+ comment(# ...)
+reserved(end)
+reserved(def) method(even_only)operator(()ident(n)operator(\))
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")inline<delimiter(#{)ident(n)delimiter(})>content( is not even)delimiter(")> reserved(if) operator(()ident(n) operator(&) integer(1)operator(\)) operator(!)operator(=) integer(0)
+ comment(# ...)
+reserved(end)
+
+
+comment(# @@PLEAC@@_12.17)
+comment(# The library archive for ruby is called Ruby Application archive,)
+comment(# or shorter RAA, and can be found at http://raa.ruby-lang.org.)
+comment(# A typical library is installed like this:)
+comment(# % gunzip some-module-4.54.tar.gz)
+comment(# % tar xf some-module-4.54.tar)
+comment(# % cd some-module-4.54.tar)
+comment(# % ruby install.rb config)
+comment(# % ruby install.rb setup)
+comment(# get superuser previleges here if needed for next step)
+comment(# % ruby install.rb install)
+
+comment(# Some modules use a different process,)
+comment(# you should find details in the documentation)
+comment(# Here is an example of such a different process)
+comment(# % ruby extconf.rb)
+comment(# % make)
+comment(# % make install)
+
+comment(# If you want the module installed in your own directory:)
+comment(# For ruby version specific libraries)
+comment(# % ruby install.rb config --site-ruby=~/lib)
+comment(# For version independent libraries)
+comment(# % ruby install.rb config --site-ruby-common=~/lib)
+
+comment(# Information about possible options for config)
+comment(# % ruby install.rb --help)
+
+comment(# If you have your own complete distribution)
+comment(# % ruby install.rb --prefix=path=~/ruby-private)
+
+
+comment(# @@PLEAC@@_13.0)
+comment(# Classes and objects in Ruby are rather straigthforward)
+reserved(class) class(Person)
+ comment(# Class variables (also called static attributes\) are prefixed by @@)
+ class_variable(@@person_counter)operator(=)integer(0)
+
+ comment(# object constructor)
+ reserved(def) method(initialize)operator(()ident(age)operator(,) ident(name)operator(,) ident(alive) operator(=) pre_constant(true)operator(\)) comment(# Default arg like in C++)
+ instance_variable(@age)operator(,) instance_variable(@name)operator(,) instance_variable(@alive) operator(=) ident(age)operator(,) ident(name)operator(,) ident(alive) comment(# Object attributes are prefixed by '@')
+ class_variable(@@person_counter) operator(+)operator(=) integer(1)
+ comment(# There is no '++' operator in Ruby. The '++'/'--' operators are in fact )
+ comment(# hidden assignments which affect variables, not objects. You cannot accomplish)
+ comment(# assignment via method. Since everything in Ruby is object, '++' and '--' )
+ comment(# contradict Ruby OO ideology. Instead '-=' and '+=' are used.)
+ reserved(end)
+
+ ident(attr_accessor) symbol(:name)operator(,) symbol(:age) comment(# This creates setter and getter methods for @name)
+ comment(# and @age. See 13.3 for detailes.)
+
+ comment(# methods modifying the receiver object usually have the '!' suffix)
+ reserved(def) method(die!)
+ instance_variable(@alive) operator(=) pre_constant(false)
+ ident(puts) string<delimiter(")inline<delimiter(#{)instance_variable(@name)delimiter(})>content( has died at the age of )inline<delimiter(#{)instance_variable(@age)delimiter(})>content(.)delimiter(")>
+ instance_variable(@alive)
+ reserved(end)
+
+ reserved(def) method(kill)operator(()ident(anotherPerson)operator(\))
+ ident(print) instance_variable(@name)operator(,) string<delimiter(')content( is killing )delimiter(')>operator(,) ident(anotherPerson)operator(.)ident(name)operator(,) string<delimiter(")content(.)char(\\n)delimiter(")>
+ ident(anotherPerson)operator(.)ident(die!)
+ reserved(end)
+
+ comment(# methods used as queries)
+ comment(# usually have the '?' suffix )
+ reserved(def) method(alive?)
+ instance_variable(@alive) operator(&&) pre_constant(true)
+ reserved(end)
+
+ reserved(def) method(year_of_birth)
+ constant(Time)operator(.)ident(now)operator(.)ident(year) operator(-) instance_variable(@age)
+ reserved(end)
+
+ comment(# Class method (also called static method\))
+ reserved(def) constant(Person)operator(.)ident(number_of_people)
+ class_variable(@@person_counter)
+ reserved(end)
+reserved(end)
+
+comment(# Using the class:)
+comment(# Create objects of class Person)
+ident(lecter) operator(=) constant(Person)operator(.)ident(new)operator(()integer(47)operator(,) string<delimiter(')content(Hannibal)delimiter(')>operator(\))
+ident(starling) operator(=) constant(Person)operator(.)ident(new)operator(()integer(29)operator(,) string<delimiter(')content(Clarice)delimiter(')>operator(,) pre_constant(true)operator(\))
+ident(pazzi) operator(=) constant(Person)operator(.)ident(new)operator(()integer(40)operator(,) string<delimiter(')content(Rinaldo)delimiter(')>operator(,) pre_constant(true)operator(\))
+
+comment(# Calling a class method)
+ident(print) string<delimiter(")content(There are )delimiter(")>operator(,) constant(Person)operator(.)ident(number_of_people)operator(,) string<delimiter(")content( Person objects)char(\\n)delimiter(")>
+
+ident(print) ident(pazzi)operator(.)ident(name)operator(,) string<delimiter(')content( is )delimiter(')>operator(,) operator(()ident(pazzi)operator(.)ident(alive?)operator(\)) operator(?) string<delimiter(')content(alive)delimiter(')> operator(:) string<delimiter(')content(dead)delimiter(')>operator(,) string<delimiter(")content(.)char(\\n)delimiter(")>
+ident(lecter)operator(.)ident(kill)operator(()ident(pazzi)operator(\))
+ident(print) ident(pazzi)operator(.)ident(name)operator(,) string<delimiter(')content( is )delimiter(')>operator(,) operator(()ident(pazzi)operator(.)ident(alive?)operator(\)) operator(?) string<delimiter(')content(alive)delimiter(')> operator(:) string<delimiter(')content(dead)delimiter(')>operator(,) string<delimiter(")content(.)char(\\n)delimiter(")>
+
+ident(print) ident(starling)operator(.)ident(name) operator(,) string<delimiter(')content( was born in )delimiter(')>operator(,) ident(starling)operator(.)ident(year_of_birth)operator(,) string<delimiter(")char(\\n)delimiter(")>
+
+
+comment(# @@PLEAC@@_13.1)
+comment(# If you don't need any initialisation in the constructor,)
+comment(# you don't need to write a constructor.)
+reserved(class) class(MyClass)
+reserved(end)
+
+reserved(class) class(MyClass)
+ reserved(def) method(initialize)
+ instance_variable(@start) operator(=) constant(Time)operator(.)ident(new)
+ instance_variable(@age) operator(=) integer(0)
+ reserved(end)
+reserved(end)
+
+reserved(class) class(MyClass)
+ reserved(def) method(initialize)operator(()ident(inithash)operator(\))
+ instance_variable(@start) operator(=) constant(Time)operator(.)ident(new)
+ instance_variable(@age) operator(=) integer(0)
+ reserved(for) ident(key)operator(,) ident(value) reserved(in) ident(inithash)
+ ident(instance_variable_set)operator(()string<delimiter(")content(@)inline<delimiter(#{)ident(key)delimiter(})>delimiter(")>operator(,) ident(value)operator(\))
+ reserved(end)
+ reserved(end)
+reserved(end)
+
+comment(# @@PLEAC@@_13.2)
+comment(# Objects are destroyed by the garbage collector.)
+comment(# The time of destroying is not predictable.)
+comment(# The ruby garbage collector can handle circular references,)
+comment(# so there is no need to write destructor for that.)
+
+comment(# There is no direct support for destructor.)
+comment(# You can call a custom function, or more specific a proc object, when the)
+comment(# garbage collector is about to destruct the object, but it is unpredictable)
+comment(# when this occurs.)
+comment(# Also if such a finalizer object has a reference to the orignal object,)
+comment(# this may prevent the original object to get garbage collected.)
+comment(# Because of this problem the finalize method below is)
+comment(# a class method and not a instance method.)
+comment(# So if you need to free resources for an object, like)
+comment(# closing a socket or kill a spawned subprocess,)
+comment(# you should do it explicitly.)
+
+reserved(class) class(MyClass)
+ reserved(def) method(initialize)
+ constant(ObjectSpace)operator(.)ident(define_finalizer)operator(()pre_constant(self)operator(,)
+ pre_constant(self)operator(.)ident(class)operator(.)ident(method)operator(()symbol(:finalize)operator(\))operator(.)ident(to_proc)operator(\))
+ reserved(end)
+ reserved(def) constant(MyClass)operator(.)ident(finalize)operator(()ident(id)operator(\))
+ ident(puts) string<delimiter(")content(Object )inline<delimiter(#{)ident(id)delimiter(})>content( dying at )inline<delimiter(#{)constant(Time)operator(.)ident(new)delimiter(})>delimiter(")>
+ reserved(end)
+reserved(end)
+
+comment(# test code)
+integer(3)operator(.)ident(times) operator({)
+ constant(MyClass)operator(.)ident(new)
+operator(})
+constant(ObjectSpace)operator(.)ident(garbage_collect)
+
+
+comment(# @@PLEAC@@_13.3)
+comment(# You can write getter and setter methods in a natural way:)
+reserved(class) class(Person)
+ reserved(def) method(name)
+ instance_variable(@name)
+ reserved(end)
+ reserved(def) method(name=)operator(()ident(name)operator(\))
+ instance_variable(@name) operator(=) ident(name)
+ reserved(end)
+reserved(end)
+
+comment(# But there is a better and shorter way)
+reserved(class) class(Person)
+ ident(attr_reader) symbol(:age)
+ ident(attr_writer) symbol(:name)
+ comment(# attr_reader and attr_writer are actually methods in class Class)
+ comment(# which set getter and setter methods for you.)
+reserved(end)
+
+comment(# There is also attr_accessor to create both setters and getters)
+reserved(class) class(Person)
+ ident(attr_accessor) symbol(:age)operator(,) symbol(:name)
+reserved(end)
+
+
+comment(# @@PLEAC@@_13.4)
+reserved(class) class(Person)
+ comment(# Class variables (also called static attributes\) are prefixed by @@)
+ class_variable(@@person_counter) operator(=) integer(0)
+
+ reserved(def) constant(Person)operator(.)ident(population)
+ class_variable(@@person_counter)
+ reserved(end)
+ reserved(def) method(initialize)
+ class_variable(@@person_counter) operator(+)operator(=) integer(1)
+ constant(ObjectSpace)operator(.)ident(define_finalizer)operator(()pre_constant(self)operator(,)
+ pre_constant(self)operator(.)ident(class)operator(.)ident(method)operator(()symbol(:finalize)operator(\))operator(.)ident(to_proc)operator(\))
+ reserved(end)
+ reserved(def) constant(Person)operator(.)ident(finalize)operator(()ident(id)operator(\))
+ class_variable(@@person_counter) operator(-)operator(=) integer(1)
+ reserved(end)
+reserved(end)
+ident(people) operator(=) operator([)operator(])
+integer(10)operator(.)ident(times) operator({)
+ ident(people)operator(.)ident(push)operator(()constant(Person)operator(.)ident(new)operator(\))
+operator(})
+ident(printf)operator(()string<delimiter(")content(There are %d people alive)delimiter(")>operator(,) constant(Person)operator(.)ident(population)operator(\))
+
+
+constant(FixedArray)operator(.)ident(class_max_bounds) operator(=) integer(100)
+ident(alpha) operator(=) constant(FixedArray)operator(.)ident(new)
+ident(puts) string<delimiter(")content(Bound on alpha is )inline<delimiter(#{)ident(alpha)operator(.)ident(max_bounds)delimiter(})>delimiter(")>
+
+ident(beta) operator(=) constant(FixedArray)operator(.)ident(new)
+ident(beta)operator(.)ident(max_bounds) operator(=) integer(50) comment(# calls the instance method)
+ident(beta)operator(.)ident(class)operator(.)ident(class_max_bounds) operator(=) integer(50) comment(# alternative, calls the class method)
+ident(puts) string<delimiter(")content(Bound on alpha is )inline<delimiter(#{)ident(alpha)operator(.)ident(max_bounds)delimiter(})>delimiter(")>
+
+reserved(class) class(FixedArray)
+ class_variable(@@bounds) operator(=) integer(7)
+
+ reserved(def) method(max_bounds)
+ class_variable(@@max_bounds)
+ reserved(end)
+ comment(# instance method, which sets the class variable)
+ reserved(def) method(max_bounds=)operator(()ident(value)operator(\))
+ class_variable(@@max_bounds) operator(=) ident(value)
+ reserved(end)
+ comment(# class method. This can only be called on a class,)
+ comment(# but not on the instances)
+ reserved(def) constant(FixedArray)operator(.)ident(class_max_bounds)operator(=)operator(()ident(value)operator(\))
+ class_variable(@@max_bounds) operator(=) ident(value)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_13.5)
+constant(PersonStruct) operator(=) constant(Struct)operator(.)ident(new)operator(()string<delimiter(")content(Person)delimiter(")>operator(,) symbol(:name)operator(,) symbol(:age)operator(,) symbol(:peers)operator(\))
+comment(# creates a class "Person::Struct", which is accessiable with the)
+comment(# constant "PersonStruct")
+ident(p) operator(=) constant(PersonStruct)operator(.)ident(new)
+ident(p) operator(=) constant(Struct)operator(::)constant(Person)operator(.)ident(new) comment(# alternative using the classname)
+ident(p)operator(.)ident(name) operator(=) string<delimiter(")content(Jason Smythe)delimiter(")>
+ident(p)operator(.)ident(age) operator(=) integer(13)
+ident(p)operator(.)ident(peers) operator(=) operator([)string<delimiter(")content(Wilbur)delimiter(")>operator(,) string<delimiter(")content(Ralph)delimiter(")>operator(,) string<delimiter(")content(Fred)delimiter(")>operator(])
+ident(p)operator([)symbol(:peers)operator(]) operator(=) operator([)string<delimiter(")content(Wilbur)delimiter(")>operator(,) string<delimiter(")content(Ralph)delimiter(")>operator(,) string<delimiter(")content(Fred)delimiter(")>operator(]) comment(# alternative access using symbol)
+ident(p)operator([)string<delimiter(")content(peers)delimiter(")>operator(]) operator(=) operator([)string<delimiter(")content(Wilbur)delimiter(")>operator(,) string<delimiter(")content(Ralph)delimiter(")>operator(,) string<delimiter(")content(Fred)delimiter(")>operator(]) comment(# alternative access using name of field)
+ident(p)operator([)integer(2)operator(]) operator(=) operator([)string<delimiter(")content(Wilbur)delimiter(")>operator(,) string<delimiter(")content(Ralph)delimiter(")>operator(,) string<delimiter(")content(Fred)delimiter(")>operator(]) comment(# alternative access using index of field)
+ident(puts) string<delimiter(")content(At age )inline<delimiter(#{)ident(p)operator(.)ident(age)delimiter(})>content(, )inline<delimiter(#{)ident(p)operator(.)ident(name)delimiter(})>content('s first friend is )inline<delimiter(#{)ident(p)operator(.)ident(peers)operator([)integer(0)operator(])delimiter(})>delimiter(")>
+
+comment(# The fields of a struct have no special type, like other ruby variables)
+comment(# you can put any objects in. Therefore the discussions how to specify)
+comment(# the types of the fields do not apply to ruby.)
+
+constant(FamilyStruct) operator(=) constant(Struct)operator(.)ident(new)operator(()string<delimiter(")content(Family)delimiter(")>operator(,) symbol(:head)operator(,) symbol(:address)operator(,) symbol(:members)operator(\))
+ident(folks) operator(=) constant(FamilyStruct)operator(.)ident(new)
+ident(folks)operator(.)ident(head) operator(=) constant(PersonStruct)operator(.)ident(new)
+ident(dad) operator(=) ident(folks)operator(.)ident(head)
+ident(dad)operator(.)ident(name) operator(=) string<delimiter(")content(John)delimiter(")>
+ident(dad)operator(.)ident(age) operator(=) integer(34)
+
+comment(# supply of own accessor method for the struct for error checking)
+reserved(class) class(PersonStruct)
+ reserved(def) method(age=)operator(()ident(value)operator(\))
+ reserved(if) operator(!)ident(value)operator(.)ident(kind_of?)operator(()constant(Integer)operator(\))
+ ident(raise)operator(()constant(ArgumentError)operator(,) string<delimiter(")content(Age )inline<delimiter(#{)ident(value)delimiter(})>content( isn't an Integer)delimiter(")>operator(\))
+ reserved(elsif) ident(value) operator(>) integer(150)
+ ident(raise)operator(()constant(ArgumentError)operator(,) string<delimiter(")content(Age )inline<delimiter(#{)ident(value)delimiter(})>content( is unreasonable)delimiter(")>operator(\))
+ reserved(end)
+ instance_variable(@age) operator(=) ident(value)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_13.6)
+comment(# The ruby Object class defines a dup and a clone method.)
+comment(# The dup method is recommended for prototype object creation.)
+comment(# The default implementation makes a shallow copy,)
+comment(# but each class can override it, for example to make a deep copy.)
+
+comment(# If you want to call 'new' directly on the instances,)
+comment(# you can create a instance method "new", which returns a new duplicate.)
+comment(# This method is distinct from the class method new.)
+comment(#)
+reserved(class) class(A)
+ reserved(def) method(new)
+ ident(dup)
+ reserved(end)
+reserved(end)
+
+ident(ob1) operator(=) constant(A)operator(.)ident(new)
+comment(# later on)
+ident(ob2) operator(=) ident(ob1)operator(.)ident(new)
+
+
+comment(# @@PLEAC@@_13.7)
+ident(methname) operator(=) string<delimiter(')content(flicker)delimiter(')>
+ident(obj)operator(.)ident(send)operator(()ident(methname)operator(,) integer(10)operator(\)) comment(# calls obj.flicker(10\))
+
+comment(# call three methods on the object, by name)
+operator([)string<delimiter(')content(start)delimiter(')>operator(,) string<delimiter(')content(run)delimiter(')>operator(,) string<delimiter(')content(stop)delimiter(')>operator(])operator(.)ident(each) reserved(do) operator(|)ident(method_string)operator(|)
+ ident(obj)operator(.)ident(send)operator(()ident(method_string)operator(\))
+reserved(end)
+
+comment(# Another way is to create a Method object)
+ident(method_obj) operator(=) ident(obj)operator(.)ident(method)operator(()string<delimiter(')content(flicker)delimiter(')>operator(\))
+comment(# And then call it)
+ident(method_obj)operator(.)ident(call)operator(()integer(10)operator(\))
+
+
+comment(# @@PLEAC@@_13.8)
+comment(# All classes in Ruby inherit from class Object)
+comment(# and thus all objects share methods defined in this class)
+
+comment(# the class of the object)
+ident(puts) ident(any_object)operator(.)ident(type)
+
+comment(# Ruby classes are actually objects of class Class and they)
+comment(# respond to methods defined in Object class as well)
+
+comment(# the superclass of this class)
+ident(puts) ident(any_object)operator(.)ident(class)operator(.)ident(superclass)
+
+comment(# ask an object whether it is an instance of particular class)
+ident(n) operator(=) float(4.7)
+ident(puts) ident(n)operator(.)ident(instance_of?)operator(()constant(Float)operator(\)) comment(# true)
+ident(puts) ident(n)operator(.)ident(instance_of?)operator(()constant(Numeric)operator(\)) comment(# false)
+
+comment(# ask an object whether it is an instance of class, one of the)
+comment(# superclasses of the object, or modules included in it)
+ident(puts) ident(n)operator(.)ident(kind_of?)operator(()constant(Float)operator(\)) comment(# true (the class\))
+ident(puts) ident(n)operator(.)ident(kind_of?)operator(()constant(Numeric)operator(\)) comment(# true (an ancestor class\))
+ident(puts) ident(n)operator(.)ident(kind_of?)operator(()constant(Comparable)operator(\)) comment(# true (a mixin module\))
+ident(puts) ident(n)operator(.)ident(kind_of?)operator(()constant(String)operator(\)) comment(# false)
+
+comment(# ask an object whether it can respond to a particular method)
+ident(puts) ident(n)operator(.)ident(respond_to?)operator(()string<delimiter(')content(+)delimiter(')>operator(\)) comment(# true)
+ident(puts) ident(n)operator(.)ident(respond_to?)operator(()string<delimiter(')content(length)delimiter(')>operator(\)) comment(# false)
+
+comment(# all methods an object can respond to)
+string<delimiter(')content(just a string)delimiter(')>operator(.)ident(methods)operator(.)ident(each) operator({) operator(|)ident(m)operator(|) ident(puts) ident(m) operator(})
+
+
+comment(# @@PLEAC@@_13.9)
+comment(# Actually any class in Ruby is inheritable)
+reserved(class) class(Person)
+ ident(attr_accessor) symbol(:age)operator(,) symbol(:name)
+ reserved(def) method(initialize)
+ instance_variable(@name)
+ instance_variable(@age)
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+ident(dude) operator(=) constant(Person)operator(.)ident(new)
+ident(dude)operator(.)ident(name) operator(=) string<delimiter(')content(Jason)delimiter(')>
+ident(dude)operator(.)ident(age) operator(=) integer(23)
+ident(printf) string<delimiter(")content(%s is age %d.)char(\\n)delimiter(")>operator(,) ident(dude)operator(.)ident(name)operator(,) ident(dude)operator(.)ident(age)
+comment(#-----------------------------)
+comment(# Inheriting from Person)
+reserved(class) class(Employee) operator(<) constant(Person)
+ ident(attr_accessor) symbol(:salary)
+reserved(end)
+comment(#-----------------------------)
+ident(empl) operator(=) constant(Employee)operator(.)ident(new)
+ident(empl)operator(.)ident(name) operator(=) string<delimiter(')content(Jason)delimiter(')>
+ident(empl)operator(.)ident(age) operator(=) integer(23)
+ident(empl)operator(.)ident(salary) operator(=) integer(200)
+ident(printf) string<delimiter(")content(%s is age %d, the salary is %d.)char(\\n)delimiter(")>operator(,) ident(empl)operator(.)ident(name)operator(,) ident(empl)operator(.)ident(age)operator(,) ident(empl)operator(.)ident(salary)
+comment(#-----------------------------)
+comment(# Any built-in class can be inherited the same way)
+reserved(class) class(WeirdString) operator(<) constant(String)
+ reserved(def) method(initialize)operator(()ident(obj)operator(\))
+ reserved(super) ident(obj)
+ reserved(end)
+ reserved(def) method(+)operator(()ident(anotherObj)operator(\)) comment(# + method in this class is overridden)
+ comment(# to return the sum of string lengths)
+ pre_constant(self)operator(.)ident(length) operator(+) ident(anotherObj)operator(.)ident(length) comment(# 'self' can be omitted)
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+ident(a) operator(=) constant(WeirdString)operator(.)ident(new)operator(()string<delimiter(')content(hello)delimiter(')>operator(\))
+ident(b) operator(=) constant(WeirdString)operator(.)ident(new)operator(()string<delimiter(')content(bye)delimiter(')>operator(\))
+
+ident(puts) ident(a) operator(+) ident(b) comment(# the overridden +)
+comment(#=> 8)
+ident(puts) ident(a)operator(.)ident(length) comment(# method from the superclass, String)
+comment(#=> 5)
+
+
+comment(# @@PLEAC@@_13.11)
+comment(# In ruby you can override the method_missing method)
+comment(# to have a solution similar to perls AUTOLOAD.)
+reserved(class) class(Person)
+
+ reserved(def) method(initialize)
+ instance_variable(@ok_fields) operator(=) string<delimiter(%w()content(name age peers parent)delimiter(\))>
+ reserved(end)
+
+ reserved(def) method(valid_attribute?)operator(()ident(name)operator(\))
+ instance_variable(@ok_fields)operator(.)ident(include?)operator(()ident(name)operator(\))
+ reserved(end)
+
+ reserved(def) method(method_missing)operator(()ident(namesymbol)operator(,) operator(*)ident(params)operator(\))
+ ident(name) operator(=) ident(namesymbol)operator(.)ident(to_s)
+ reserved(return) reserved(if) ident(name) operator(=)operator(~) regexp<delimiter(/)content(^A-Z)delimiter(/)>
+ reserved(if) ident(name)operator(.)ident(to_s)operator([)operator(-)integer(1)operator(]) operator(==) operator(()string<delimiter(')content(=)delimiter(')>operator([)integer(0)operator(])operator(\)) comment(# we have a setter)
+ ident(isSetter) operator(=) pre_constant(true)
+ ident(name)operator(.)ident(sub!)operator(()regexp<delimiter(/)content(=$)delimiter(/)>operator(,) string<delimiter(')delimiter(')>operator(\))
+ reserved(end)
+ reserved(if) ident(valid_attribute?)operator(()ident(name)operator(\))
+ reserved(if) ident(isSetter)
+ ident(instance_variable_set)operator(()string<delimiter(")content(@)inline<delimiter(#{)ident(name)delimiter(})>delimiter(")>operator(,) operator(*)ident(params)operator(\))
+ reserved(else)
+ ident(instance_variable_get)operator(()string<delimiter(")content(@)inline<delimiter(#{)ident(name)delimiter(})>delimiter(")>operator(,) operator(*)ident(params)operator(\))
+ reserved(end)
+ reserved(else)
+ comment(# if no annestor is responsible,)
+ comment(# the Object class will throw a NoMethodError exception)
+ reserved(super)operator(()ident(namesymbol)operator(,) operator(*)ident(params)operator(\))
+ reserved(end)
+ reserved(end)
+
+ reserved(def) method(new)
+ ident(kid) operator(=) constant(Person)operator(.)ident(new)
+ ident(kid)operator(.)ident(parent) operator(=) pre_constant(self)
+ ident(kid)
+ reserved(end)
+
+reserved(end)
+
+ident(dad) operator(=) constant(Person)operator(.)ident(new)
+ident(dad)operator(.)ident(name) operator(=) string<delimiter(")content(Jason)delimiter(")>
+ident(dad)operator(.)ident(age) operator(=) integer(23)
+ident(kid) operator(=) ident(dad)operator(.)ident(new)
+ident(kid)operator(.)ident(name) operator(=) string<delimiter(")content(Rachel)delimiter(")>
+ident(kid)operator(.)ident(age) operator(=) integer(2)
+ident(puts) string<delimiter(")content(Kid's parent is )inline<delimiter(#{)ident(kid)operator(.)ident(parent)operator(.)ident(name)delimiter(})>delimiter(")>
+ident(puts) ident(dad)
+ident(puts) ident(kid)
+
+reserved(class) class(Employee) operator(<) constant(Person)
+ reserved(def) method(initialize)
+ reserved(super)
+ instance_variable(@ok_fields)operator(.)ident(push)operator(()string<delimiter(")content(salary)delimiter(")>operator(,) string<delimiter(")content(boss)delimiter(")>operator(\))
+ reserved(end)
+ reserved(def) method(ok_fields)
+ instance_variable(@ok_fields)
+ reserved(end)
+reserved(end)
+
+
+comment(# @@PLEAC@@_13.13)
+comment(# The ruby garbage collector pretends to cope with circular structures.)
+comment(# You can test it with this code:)
+reserved(class) class(RingNode)
+ ident(attr_accessor) symbol(:next)
+ ident(attr_accessor) symbol(:prev)
+ ident(attr_reader) symbol(:name)
+
+ reserved(def) method(initialize)operator(()ident(aName)operator(\))
+ instance_variable(@name) operator(=) ident(aName)
+ constant(ObjectSpace)operator(.)ident(define_finalizer)operator(()pre_constant(self)operator(,)
+ pre_constant(self)operator(.)ident(class)operator(.)ident(method)operator(()symbol(:finalize)operator(\))operator(.)ident(to_proc)operator(\))
+ reserved(end)
+
+ reserved(def) constant(RingNode)operator(.)ident(finalize)operator(()ident(id)operator(\))
+ ident(puts) string<delimiter(")content(Node )inline<delimiter(#{)ident(id)delimiter(})>content( dying)delimiter(")>
+ reserved(end)
+
+ reserved(def) constant(RingNode)operator(.)ident(show_all_objects)
+ constant(ObjectSpace)operator(.)ident(each_object) operator({)operator(|)ident(id)operator(|)
+ ident(puts) ident(id)operator(.)ident(name) reserved(if) ident(id)operator(.)ident(class) operator(==) constant(RingNode)
+ operator(})
+ reserved(end)
+reserved(end)
+
+reserved(def) method(create_test)
+ ident(a) operator(=) constant(RingNode)operator(.)ident(new)operator(()string<delimiter(")content(Node A)delimiter(")>operator(\))
+ ident(b) operator(=) constant(RingNode)operator(.)ident(new)operator(()string<delimiter(")content(Node B)delimiter(")>operator(\))
+ ident(c) operator(=) constant(RingNode)operator(.)ident(new)operator(()string<delimiter(")content(Node C)delimiter(")>operator(\))
+ ident(a)operator(.)ident(next) operator(=) ident(b)
+ ident(b)operator(.)ident(next) operator(=) ident(c)
+ ident(c)operator(.)ident(next) operator(=) ident(a)
+ ident(a)operator(.)ident(prev) operator(=) ident(c)
+ ident(c)operator(.)ident(prev) operator(=) ident(b)
+ ident(b)operator(.)ident(prev) operator(=) ident(a)
+
+ ident(a) operator(=) pre_constant(nil)
+ ident(b) operator(=) pre_constant(nil)
+ ident(c) operator(=) pre_constant(nil)
+reserved(end)
+
+ident(create_test)
+constant(RingNode)operator(.)ident(show_all_objects)
+constant(ObjectSpace)operator(.)ident(garbage_collect)
+ident(puts) string<delimiter(")content(After garbage collection)delimiter(")>
+constant(RingNode)operator(.)ident(show_all_objects)
+
+
+comment(# @@PLEAC@@_13.14)
+reserved(class) class(String)
+ reserved(def) method(<=>)operator(()ident(other)operator(\))
+ pre_constant(self)operator(.)ident(casecmp) ident(other)
+ reserved(end)
+reserved(end)
+
+comment(# There is no way to directly overload the '""' (stringify\) )
+comment(# operator in Ruby. However, by convention, classes which )
+comment(# can reasonably be converted to a String will define a )
+comment(# 'to_s' method as in the TimeNumber class defined below.)
+comment(# The 'puts' method will automatcally call an object's)
+comment(# 'to_s' method as is demonstrated below.)
+comment(# Furthermore, if a class defines a to_str method, an object of that)
+comment(# class can be used most any place where the interpreter is looking )
+comment(# for a String value.)
+
+comment(#---------------------------------------)
+comment(# NOTE: Ruby has a builtin Time class which would usually be used )
+comment(# to manipulate time objects, the following is supplied for)
+comment(# educational purposes to demonstrate operator overloading.)
+comment(#)
+reserved(class) class(TimeNumber)
+ ident(attr_accessor) symbol(:hours)operator(,)symbol(:minutes)operator(,)symbol(:seconds)
+ reserved(def) method(initialize)operator(() ident(hours)operator(,) ident(minutes)operator(,) ident(seconds)operator(\))
+ instance_variable(@hours) operator(=) ident(hours)
+ instance_variable(@minutes) operator(=) ident(minutes)
+ instance_variable(@seconds) operator(=) ident(seconds)
+ reserved(end)
+
+ reserved(def) method(to_s)
+ reserved(return) ident(sprintf)operator(() string<delimiter(")content(%d:%02d:%02d)delimiter(")>operator(,) instance_variable(@hours)operator(,) instance_variable(@minutes)operator(,) instance_variable(@seconds)operator(\))
+ reserved(end)
+
+ reserved(def) method(to_str)
+ ident(to_s)
+ reserved(end)
+
+ reserved(def) method(+)operator(() ident(other)operator(\))
+ ident(seconds) operator(=) instance_variable(@seconds) operator(+) ident(other)operator(.)ident(seconds)
+ ident(minutes) operator(=) instance_variable(@minutes) operator(+) ident(other)operator(.)ident(minutes)
+ ident(hours) operator(=) instance_variable(@hours) operator(+) ident(other)operator(.)ident(hours)
+ reserved(if) ident(seconds) operator(>)operator(=) integer(60)
+ ident(seconds) operator(%=) integer(60)
+ ident(minutes) operator(+)operator(=) integer(1)
+ reserved(end)
+ reserved(if) ident(minutes) operator(>)operator(=) integer(60)
+ ident(minutes) operator(%=) integer(60)
+ ident(hours) operator(+)operator(=) integer(1)
+ reserved(end)
+ reserved(return) constant(TimeNumber)operator(.)ident(new)operator(()ident(hours)operator(,) ident(minutes)operator(,) ident(seconds)operator(\))
+ reserved(end)
+
+ reserved(def) method(-)operator(()ident(other)operator(\))
+ ident(raise) constant(NotImplementedError)
+ reserved(end)
+
+ reserved(def) method(*)operator(()ident(other)operator(\))
+ ident(raise) constant(NotImplementedError)
+ reserved(end)
+
+ reserved(def) method(/)operator(() ident(other)operator(\))
+ ident(raise) constant(NotImplementedError)
+ reserved(end)
+reserved(end)
+
+ident(t1) operator(=) constant(TimeNumber)operator(.)ident(new)operator(()integer(0)operator(,) integer(58)operator(,) integer(59)operator(\))
+ident(sec) operator(=) constant(TimeNumber)operator(.)ident(new)operator(()integer(0)operator(,) integer(0)operator(,) integer(1)operator(\))
+ident(min) operator(=) constant(TimeNumber)operator(.)ident(new)operator(()integer(0)operator(,) integer(1)operator(,) integer(0)operator(\))
+ident(puts) ident(t1) operator(+) ident(sec) operator(+) ident(min) operator(+) ident(min)
+
+comment(#-----------------------------)
+comment(# StrNum class example: Ruby's builtin String class already has the )
+comment(# capabilities outlined in StrNum Perl example, however the '*' operator)
+comment(# on Ruby's String class acts differently: It creates a string which)
+comment(# is the original string repeated N times.)
+comment(#)
+comment(# Using Ruby's String class as is in this example:)
+ident(x) operator(=) string<delimiter(")content(Red)delimiter(")>operator(;) ident(y) operator(=) string<delimiter(")content(Black)delimiter(")>
+ident(z) operator(=) ident(x)operator(+)ident(y)
+ident(r) operator(=) ident(z)operator(*)integer(3) comment(# r is "RedBlackRedBlackRedBlack")
+ident(puts) string<delimiter(")content(values are )inline<delimiter(#{)ident(x)delimiter(})>content(, )inline<delimiter(#{)ident(y)delimiter(})>content(, )inline<delimiter(#{)ident(z)delimiter(})>content(, and )inline<delimiter(#{)ident(r)delimiter(})>delimiter(")>
+ident(print) string<delimiter(")inline<delimiter(#{)ident(x)delimiter(})>content( is )delimiter(")>operator(,) ident(x) operator(<) ident(y) operator(?) string<delimiter(")content(LT)delimiter(")> operator(:) string<delimiter(")content(GE)delimiter(")>operator(,) string<delimiter(")content( )inline<delimiter(#{)ident(y)delimiter(})>char(\\n)delimiter(")>
+comment(# prints:)
+comment(# values are Red, Black, RedBlack, and RedBlackRedBlackRedBlack)
+comment(# Red is GE Black)
+
+comment(#-----------------------------)
+reserved(class) class(FixNum)
+ constant(REGEX) operator(=) regexp<delimiter(/)content(()char(\\.)char(\\d)content(*\))delimiter(/)>
+ constant(DEFAULT_PLACES) operator(=) integer(0)
+ ident(attr_accessor) symbol(:value)operator(,) symbol(:places)
+ reserved(def) method(initialize)operator(()ident(value)operator(,) ident(places) operator(=) pre_constant(nil)operator(\))
+ instance_variable(@value) operator(=) ident(value)
+ reserved(if) ident(places)
+ instance_variable(@places) operator(=) ident(places)
+ reserved(else)
+ ident(m) operator(=) constant(REGEX)operator(.)ident(match)operator(()ident(value)operator(.)ident(to_s)operator(\))
+ reserved(if) ident(m)
+ instance_variable(@places) operator(=) ident(m)operator([)integer(0)operator(])operator(.)ident(length) operator(-) integer(1)
+ reserved(else)
+ instance_variable(@places) operator(=) constant(DEFAULT_PLACES)
+ reserved(end)
+ reserved(end)
+ reserved(end)
+
+ reserved(def) method(+)operator(()ident(other)operator(\))
+ constant(FixNum)operator(.)ident(new)operator(()instance_variable(@value) operator(+) ident(other)operator(.)ident(value)operator(,) ident(max)operator(()instance_variable(@places)operator(,) ident(other)operator(.)ident(places)operator(\))operator(\))
+ reserved(end)
+
+ reserved(def) method(*)operator(()ident(other)operator(\))
+ constant(FixNum)operator(.)ident(new)operator(()instance_variable(@value) operator(*) ident(other)operator(.)ident(value)operator(,) ident(max)operator(()instance_variable(@places)operator(,) ident(other)operator(.)ident(places)operator(\))operator(\))
+ reserved(end)
+
+ reserved(def) method(/)operator(()ident(other)operator(\))
+ ident(puts) string<delimiter(")content(Divide: )inline<delimiter(#{)instance_variable(@value)operator(.)ident(to_f)operator(/)ident(other)operator(.)ident(value)operator(.)ident(to_f)delimiter(})>delimiter(")>
+ ident(result) operator(=) constant(FixNum)operator(.)ident(new)operator(()instance_variable(@value)operator(.)ident(to_f)operator(/)ident(other)operator(.)ident(value)operator(.)ident(to_f)operator(\))
+ ident(result)operator(.)ident(places) operator(=) ident(max)operator(()ident(result)operator(.)ident(places)operator(,)ident(other)operator(.)ident(places)operator(\))
+ ident(result)
+ reserved(end)
+
+ reserved(def) method(to_s)
+ ident(sprintf)operator(()string<delimiter(")content(STR%s: %.*f)delimiter(")>operator(,) pre_constant(self)operator(.)ident(class)operator(.)ident(to_s) operator(,) instance_variable(@places)operator(,) instance_variable(@value)operator(\)) comment(#.)
+ reserved(end)
+
+ reserved(def) method(to_str)
+ ident(to_s)
+ reserved(end)
+
+ reserved(def) method(to_i) comment(#convert to int)
+ instance_variable(@value)operator(.)ident(to_i)
+ reserved(end)
+
+ reserved(def) method(to_f) comment(#convert to float`)
+ instance_variable(@value)operator(.)ident(to_f)
+ reserved(end)
+
+ ident(private)
+ reserved(def) method(max)operator(()ident(a)operator(,)ident(b)operator(\))
+ ident(a) operator(>) ident(b) operator(?) ident(a) operator(:) ident(b)
+ reserved(end)
+reserved(end)
+
+reserved(def) method(demo)operator(()operator(\))
+ ident(x) operator(=) constant(FixNum)operator(.)ident(new)operator(()integer(40)operator(\))
+ ident(y) operator(=) constant(FixNum)operator(.)ident(new)operator(()integer(12)operator(,) integer(0)operator(\))
+
+ ident(puts) string<delimiter(")content(sum of )inline<delimiter(#{)ident(x)delimiter(})>content( and )inline<delimiter(#{)ident(y)delimiter(})>content( is )inline<delimiter(#{)ident(x)operator(+)ident(y)delimiter(})>delimiter(")>
+ ident(puts) string<delimiter(")content(product of )inline<delimiter(#{)ident(x)delimiter(})>content( and )inline<delimiter(#{)ident(y)delimiter(})>content( is )inline<delimiter(#{)ident(x)operator(*)ident(y)delimiter(})>delimiter(")>
+
+ ident(z) operator(=) ident(x)operator(/)ident(y)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(z)delimiter(})>content( has )inline<delimiter(#{)ident(z)operator(.)ident(places)delimiter(})>content( places)delimiter(")>
+ reserved(unless) ident(z)operator(.)ident(places)
+ ident(z)operator(.)ident(places) operator(=) integer(2)
+ reserved(end)
+
+ ident(puts) string<delimiter(")content(div of )inline<delimiter(#{)ident(x)delimiter(})>content( by )inline<delimiter(#{)ident(y)delimiter(})>content( is )inline<delimiter(#{)ident(z)delimiter(})>delimiter(")>
+ ident(puts) string<delimiter(")content(square of that is )inline<delimiter(#{)ident(z)operator(*)ident(z)delimiter(})>delimiter(")>
+reserved(end)
+
+reserved(if) pre_constant(__FILE__) operator(==) global_variable($0)
+ ident(demo)operator(()operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_14.1)
+comment(# There are dbm, sdbm, gdbm modules)
+comment(# and the bdb module for accessing the berkeley db)
+comment(# sdbm seem to be available on the most systems,)
+comment(# so we use it here)
+comment(#)
+ident(require) string<delimiter(")content(sdbm)delimiter(")>
+constant(SDBM)operator(.)ident(open)operator(()string<delimiter(")content(filename)delimiter(")>operator(,) integer(0666)operator(\)) operator({) operator(|)ident(dbobj)operator(|)
+ comment(# raises exception if open error)
+
+ comment(# the returned sdbm-dbobj has most of the methods of a hash)
+ ident(v) operator(=) ident(dbobj)operator([)string<delimiter(")content(key)delimiter(")>operator(])
+ ident(dbobj)operator([)string<delimiter(")content(key)delimiter(")>operator(]) operator(=) string<delimiter(")content(newvalue)delimiter(")>
+ reserved(if) ident(dbobj)operator(.)ident(has_key?)operator(()string<delimiter(")content(key)delimiter(")>operator(\))
+ comment(# ...)
+ reserved(end)
+ ident(dbobj)operator(.)ident(delete)operator(()string<delimiter(")content(key2)delimiter(")>operator(\))
+operator(})
+comment(# database is open only inside the block.)
+
+comment(# It is also possible to use a open .. close pair:)
+ident(dbobj) operator(=) constant(SDBM)operator(.)ident(open)operator(()string<delimiter(")content(filename)delimiter(")>operator(,) integer(0666)operator(\))
+comment(#.. do something with dbobj)
+ident(dbobj)operator(.)ident(close)
+
+comment(#!/usr/bin/ruby -w)
+comment(# userstats - generate statistics on who is logged in)
+comment(# call with usernames as argument to display the totals)
+comment(# for the given usernames, call with "ALL" to display all users)
+
+ident(require) string<delimiter(")content(sdbm)delimiter(")>
+ident(filename) operator(=) string<delimiter(')content(/tmp/userstats.db)delimiter(')>
+constant(SDBM)operator(.)ident(open)operator(()ident(filename)operator(,) integer(0666)operator(\)) operator({) operator(|)ident(dbobj)operator(|)
+ reserved(if) pre_constant(ARGV)operator(.)ident(length) operator(>) integer(0)
+ reserved(if) pre_constant(ARGV)operator([)integer(0)operator(]) operator(==) string<delimiter(")content(ALL)delimiter(")>
+ comment(# ARGV is constant, so we need the variable userlist)
+ ident(userlist) operator(=) ident(dbobj)operator(.)ident(keys)operator(()operator(\))operator(.)ident(sort)operator(()operator(\))
+ reserved(else)
+ ident(userlist) operator(=) pre_constant(ARGV)
+ reserved(end)
+ ident(userlist)operator(.)ident(each) operator({) operator(|)ident(user)operator(|)
+ ident(print) string<delimiter(")inline<delimiter(#{)ident(user)delimiter(})>char(\\t)inline<delimiter(#{)ident(dbobj)operator([)ident(user)operator(])delimiter(})>char(\\n)delimiter(")>
+ operator(})
+ reserved(else)
+ ident(who) operator(=) shell<delimiter(`)content(who)delimiter(`)>
+ ident(who)operator(.)ident(split)operator(()string<delimiter(")char(\\n)delimiter(")>operator(\))operator(.)ident(each) operator({) operator(|)ident(line)operator(|)
+ ident(md) operator(=) regexp<delimiter(/)content(^()char(\\S)content(+\))delimiter(/)>operator(.)ident(match)operator(()ident(line)operator(\))
+ ident(raise) string<delimiter(")content(Bad line from who: )inline<delimiter(#{)ident(line)delimiter(})>delimiter(")> reserved(unless) ident(md)
+ comment(# sdbm stores only strings, so "+=" doesn't work,)
+ comment(# we need to convert them expicitly back to integer.)
+ reserved(if) ident(dbobj)operator(.)ident(has_key?)operator(()ident(md)operator([)integer(0)operator(])operator(\))
+ ident(dbobj)operator([)ident(md)operator([)integer(0)operator(])operator(]) operator(=) ident(dbobj)operator([)ident(md)operator([)integer(0)operator(])operator(])operator(.)ident(to_i) operator(+) integer(1)
+ reserved(else)
+ ident(dbobj)operator([)ident(md)operator([)integer(0)operator(])operator(]) operator(=) string<delimiter(")content(1)delimiter(")>
+ reserved(end)
+ operator(})
+ reserved(end)
+operator(})
+
+
+comment(# @@PLEAC@@_14.2)
+comment(# using open and clear)
+ident(dbobj) operator(=) constant(SDBM)operator(.)ident(open)operator(()string<delimiter(")content(filename)delimiter(")>operator(,) integer(0666)operator(\))
+ident(dbobj)operator(.)ident(clear)operator(()operator(\))
+ident(dbobj)operator(.)ident(close)operator(()operator(\))
+comment(# deleting file and recreating it)
+comment(# the filenames depend on the flavor of dbm you use,)
+comment(# for example sdbm has two files named filename.pag and filename.dir,)
+comment(# so you need to delete both files)
+reserved(begin)
+ constant(File)operator(.)ident(delete)operator(()string<delimiter(")content(filename)delimiter(")>operator(\))
+ comment(# raises Exception if not exist)
+ ident(dbobj) operator(=) constant(SDBM)operator(.)ident(open)operator(()string<delimiter(")content(filename)delimiter(")>operator(,) integer(0666)operator(\))
+reserved(rescue)
+ comment(# add error handling here)
+reserved(end)
+
+
+comment(# @@PLEAC@@_14.3)
+comment(# sdbm2gdbm: converts sdbm database to a gdbm database)
+ident(require) string<delimiter(")content(sdbm)delimiter(")>
+ident(require) string<delimiter(")content(gdbm)delimiter(")>
+
+reserved(unless) pre_constant(ARGV)operator(.)ident(length) operator(==) integer(2)
+ ident(fail) string<delimiter(")content(usage: sdbm2gdbm infile outfile)delimiter(")>
+reserved(end)
+ident(infile) operator(=) pre_constant(ARGV)operator([)integer(0)operator(])
+ident(outfile) operator(=) pre_constant(ARGV)operator([)integer(1)operator(])
+
+ident(sdb) operator(=) constant(SDBM)operator(.)ident(open)operator(()ident(infile)operator(\))
+ident(gdb) operator(=) constant(GDBM)operator(.)ident(open)operator(()ident(outfile)operator(,) integer(0666)operator(\))
+ident(sdb)operator(.)ident(each) operator({) operator(|)ident(key)operator(,) ident(val)operator(|)
+ ident(gdb)operator([)ident(key)operator(]) operator(=) ident(val)
+operator(})
+ident(gdb)operator(.)ident(close)
+ident(sdb)operator(.)ident(close)
+
+
+comment(# @@PLEAC@@_14.4)
+comment(#!/usr/bin/ruby -w)
+comment(# dbmmerge: merges two dbm databases)
+ident(require) string<delimiter(")content(sdbm)delimiter(")>
+
+reserved(unless) pre_constant(ARGV)operator(.)ident(length) operator(==) integer(3)
+ ident(fail) string<delimiter(")content(usage: dbmmerge indb1 indb2 outdb)delimiter(")>
+reserved(end)
+ident(infile1) operator(=) pre_constant(ARGV)operator([)integer(0)operator(])
+ident(infile2) operator(=) pre_constant(ARGV)operator([)integer(0)operator(])
+ident(outfile) operator(=) pre_constant(ARGV)operator([)integer(2)operator(])
+
+ident(in1) operator(=) constant(SDBM)operator(.)ident(open)operator(()ident(infile1)operator(,) pre_constant(nil)operator(\))
+ident(in2) operator(=) constant(SDBM)operator(.)ident(open)operator(()ident(infile2)operator(,) pre_constant(nil)operator(\))
+ident(outdb) operator(=) constant(SDBM)operator(.)ident(open)operator(()ident(outfile)operator(,) integer(0666)operator(\))
+
+operator([)ident(in1)operator(,) ident(in2)operator(])operator(.)ident(each) operator({) operator(|)ident(indb)operator(|)
+ ident(indb)operator(.)ident(each) operator({) operator(|)ident(key)operator(,) ident(val)operator(|)
+ reserved(if) ident(outdb)operator(.)ident(has_key?)operator(()ident(key)operator(\))
+ comment(# decide which value to set.)
+ comment(# set outdb[key] if necessary)
+ reserved(else)
+ ident(outdb)operator([)ident(key)operator(]) operator(=) ident(val)
+ reserved(end)
+ operator(})
+operator(})
+ident(in1)operator(.)ident(close)
+ident(in2)operator(.)ident(close)
+ident(outdb)operator(.)ident(close)
+
+
+comment(# @@PLEAC@@_14.7)
+comment(# we write a tie method that extends the Array class.)
+comment(# It reads the file into the memory, executes the code block)
+comment(# in which you can manipulate the array as needed, and writes)
+comment(# the array back to the file after the end of the block execution)
+reserved(class) class(Array)
+ reserved(def) method(tie)operator(()ident(filename)operator(,) ident(flags)operator(\))
+ constant(File)operator(.)ident(open)operator(()ident(filename)operator(,) ident(flags)operator(\)) operator({) operator(|)ident(f)operator(|)
+ ident(f)operator(.)ident(each_line) operator({) operator(|)ident(line)operator(|)
+ pre_constant(self)operator(.)ident(push)operator(()ident(line)operator(.)ident(chomp)operator(\))
+ operator(})
+ reserved(yield)
+ ident(f)operator(.)ident(rewind)
+ ident(each) operator({) operator(|)ident(line)operator(|)
+ reserved(if) ident(line)
+ ident(f)operator(.)ident(puts)operator(()ident(line)operator(\))
+ reserved(else)
+ ident(f)operator(.)ident(puts) string<delimiter(")delimiter(")>
+ reserved(end)
+ operator(})
+ operator(})
+ reserved(end)
+reserved(end)
+
+ident(array) operator(=) constant(Array)operator(.)ident(new)
+ident(array)operator(.)ident(tie)operator(()string<delimiter(")content(/tmp/textfile.txt)delimiter(")>operator(,) constant(File)operator(::)constant(RDWR)operator(|)constant(File)operator(::)constant(CREAT)operator(\)) operator({)
+ ident(array)operator([)integer(4)operator(]) operator(=) string<delimiter(")content(a new line 4)delimiter(")>
+operator(})
+
+comment(# The tied array can be manipulated like a normal array,)
+comment(# so there is no need for a special API, and the recno_demo program)
+comment(# to demonstrate is API is useless)
+
+
+comment(# tied array demo: show how to use array with a tied file)
+ident(filename) operator(=) string<delimiter(")content(db_file.txt)delimiter(")>
+ident(lines) operator(=) constant(Array)operator(.)ident(new)
+constant(File)operator(.)ident(unlink)operator(()ident(filename)operator(\)) reserved(if) constant(File)operator(.)ident(exists?)operator(()ident(filename)operator(\))
+ident(lines)operator(.)ident(tie)operator(()ident(filename)operator(,) constant(File)operator(::)constant(RDWR) operator(|) constant(File)operator(::)constant(CREAT)operator(\)) operator({)
+ comment(# first create a textfile to play with)
+ ident(lines)operator([)integer(0)operator(]) operator(=) string<delimiter(")content(zero)delimiter(")>
+ ident(lines)operator([)integer(1)operator(]) operator(=) string<delimiter(")content(one)delimiter(")>
+ ident(lines)operator([)integer(2)operator(]) operator(=) string<delimiter(")content(two)delimiter(")>
+ ident(lines)operator([)integer(3)operator(]) operator(=) string<delimiter(")content(three)delimiter(")>
+ ident(lines)operator([)integer(4)operator(]) operator(=) string<delimiter(")content(four)delimiter(")>
+
+ comment(# print the records in order.)
+ comment(# Opposed to perl, the tied array behaves exactly as a normal array)
+ ident(puts) string<delimiter(")char(\\n)content(Original)delimiter(")>
+ reserved(for) ident(i) reserved(in) integer(0)operator(..)operator(()ident(lines)operator(.)ident(length)operator(-)integer(1)operator(\))
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(i)delimiter(})>content(: )inline<delimiter(#{)ident(lines)operator([)ident(i)operator(])delimiter(})>delimiter(")>
+ reserved(end)
+
+ comment(#use push and pop)
+ ident(a) operator(=) ident(lines)operator(.)ident(pop)
+ ident(lines)operator(.)ident(push)operator(()string<delimiter(")content(last)delimiter(")>operator(\))
+ ident(puts)operator(()string<delimiter(")content(The last line was [)inline<delimiter(#{)ident(a)delimiter(})>content(])delimiter(")>operator(\))
+
+ comment(#use shift and unshift)
+ ident(a) operator(=) ident(lines)operator(.)ident(shift)
+ ident(lines)operator(.)ident(unshift)operator(()string<delimiter(")content(first)delimiter(")>operator(\))
+ ident(puts)operator(()string<delimiter(")content(The first line was [)inline<delimiter(#{)ident(a)delimiter(})>content(])delimiter(")>operator(\))
+
+ comment(# add record after record 2)
+ ident(i) operator(=) integer(2)
+ ident(lines)operator(.)ident(insert)operator(()ident(i) operator(+) integer(1)operator(,) string<delimiter(")content(Newbie)delimiter(")>operator(\))
+
+ comment(# add record before record one)
+ ident(i) operator(=) integer(1)
+ ident(lines)operator(.)ident(insert)operator(()ident(i)operator(,) string<delimiter(")content(New One)delimiter(")>operator(\))
+
+ comment(# delete record 3)
+ ident(lines)operator(.)ident(delete_at)operator(()integer(3)operator(\))
+
+ comment(#now print the records in reverse order)
+ ident(puts) string<delimiter(")char(\\n)content(Reverse)delimiter(")>
+ operator(()ident(lines)operator(.)ident(length) operator(-) integer(1)operator(\))operator(.)ident(downto)operator(()integer(0)operator(\))operator({) operator(|)ident(i)operator(|)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(i)delimiter(})>content(: )inline<delimiter(#{)ident(lines)operator([)ident(i)operator(])delimiter(})>delimiter(")>
+ operator(})
+
+operator(})
+
+
+comment(# @@PLEAC@@_14.8)
+comment(# example to store complex data in a database)
+comment(# uses marshall from the standard library)
+ident(require) string<delimiter(")content(sdbm)delimiter(")>
+ident(db) operator(=) constant(SDBM)operator(.)ident(open)operator(()string<delimiter(")content(pleac14-8-database)delimiter(")>operator(,) integer(0666)operator(\))
+
+comment(# convert the Objects into strings and back by using the Marshal module.)
+comment(# Most normal objects can be converted out of the box,)
+comment(# but not special things like procedure objects,)
+comment(# IO instance variables, singleton objects)
+
+ident(db)operator([)string<delimiter(")content(Tom Christiansen)delimiter(")>operator(]) operator(=) constant(Marshal)operator(.)ident(dump)operator(()operator([)string<delimiter(")content(book author)delimiter(")>operator(,) string<delimiter(")content(tchrist@perl.com)delimiter(")>operator(])operator(\))
+ident(db)operator([)string<delimiter(")content(Tom Boutell)delimiter(")>operator(]) operator(=) constant(Marshal)operator(.)ident(dump)operator(()operator([)string<delimiter(")content(shareware author)delimiter(")>operator(,)
+string<delimiter(")content(boutell@boutell.com)delimiter(")>operator(])operator(\))
+
+ident(name1) operator(=) string<delimiter(")content(Tom Christiansen)delimiter(")>
+ident(name2) operator(=) string<delimiter(")content(Tom Boutell)delimiter(")>
+
+ident(tom1) operator(=) constant(Marshal)operator(.)ident(load)operator(()ident(db)operator([)ident(name1)operator(])operator(\))
+ident(tom2) operator(=) constant(Marshal)operator(.)ident(load)operator(()ident(db)operator([)ident(name2)operator(])operator(\))
+
+ident(puts) string<delimiter(")content(Two Toming: )inline<delimiter(#{)ident(tom1)delimiter(})>content( )inline<delimiter(#{)ident(tom2)delimiter(})>delimiter(")>
+
+reserved(if) ident(tom1)operator([)integer(0)operator(]) operator(==) ident(tom2)operator([)integer(0)operator(]) operator(&&) ident(tom1)operator([)integer(1)operator(]) operator(==) ident(tom2)operator([)integer(1)operator(])
+ ident(puts) string<delimiter(")content(You're having runtime fun with one Tom made two.)delimiter(")>
+reserved(else)
+ ident(puts) string<delimiter(")content(No two Toms are ever alike)delimiter(")>
+reserved(end)
+
+comment(# To change parts of an entry, get the whole entry, change the parts,)
+comment(# and save the whole entry back)
+ident(entry) operator(=) constant(Marshal)operator(.)ident(load)operator(()ident(db)operator([)string<delimiter(")content(Tom Boutell)delimiter(")>operator(])operator(\))
+ident(entry)operator([)integer(0)operator(]) operator(=) string<delimiter(")content(Poet Programmer)delimiter(")>
+ident(db)operator([)string<delimiter(")content(Tom Boutell)delimiter(")>operator(]) operator(=) constant(Marshal)operator(.)ident(dump)operator(()ident(entry)operator(\))
+ident(db)operator(.)ident(close)
+
+
+comment(# @@PLEAC@@_14.9)
+comment(# example to make data persistent)
+comment(# uses Marshal from the standard lib)
+comment(# Stores the data in a simple file,)
+comment(# see 14.8 on how to store it in a dbm file)
+
+comment(# The BEGIN block is executed before the rest of the script)
+comment(# we use global variables here because local variables)
+comment(# will go out of scope and are not accessible from the main script)
+
+reserved(BEGIN) operator({)
+ global_variable($persistent_store) operator(=) string<delimiter(")content(persitence.dat)delimiter(")>
+ reserved(begin)
+ constant(File)operator(.)ident(open)operator(()global_variable($persistent_store)operator(\)) reserved(do) operator(|)ident(f)operator(|)
+ global_variable($stringvariable1) operator(=) constant(Marshal)operator(.)ident(load)operator(()ident(f)operator(\))
+ global_variable($arrayvariable2) operator(=) constant(Marshal)operator(.)ident(load)operator(()ident(f)operator(\))
+ reserved(end)
+ reserved(rescue)
+ ident(puts) string<delimiter(")content(Can not open )inline<delimiter(#{)global_variable($persistent_store)delimiter(})>delimiter(")>
+ comment(# Initialisation if this script runs the first time)
+ global_variable($stringvariable1) operator(=) string<delimiter(")delimiter(")>
+ global_variable($arrayvariable2) operator(=) operator([)operator(])
+ reserved(end)
+operator(})
+
+reserved(END) operator({)
+ constant(File)operator(.)ident(open)operator(()global_variable($persistent_store)operator(,) string<delimiter(")content(w+)delimiter(")>operator(\)) reserved(do) operator(|)ident(f)operator(|)
+ constant(Marshal)operator(.)ident(dump)operator(()global_variable($stringvariable1)operator(,) ident(f)operator(\))
+ constant(Marshal)operator(.)ident(dump)operator(()global_variable($arrayvariable2)operator(,) ident(f)operator(\))
+ reserved(end)
+operator(})
+
+comment(# simple test program)
+ident(puts) global_variable($stringvariable1)
+ident(puts) global_variable($arrayvariable2)
+global_variable($stringvariable1) operator(=) string<delimiter(")content(Hello World)delimiter(")>
+global_variable($arrayvariable2)operator(.)ident(push)operator(()integer(5)operator(\))
+ident(puts) global_variable($stringvariable1)
+ident(puts) global_variable($arrayvariable2)
+
+
+comment(# @@PLEAC@@_14.10)
+comment(#!/usr/bin/ruby -w)
+comment(# Ruby has a dbi module with an architecture similar)
+comment(# to the Perl dbi module: the dbi module provides an unified)
+comment(# interface and uses specialized drivers for each dbms vendor)
+comment(#)
+reserved(begin)
+ constant(DBI)operator(.)ident(connect)operator(()string<delimiter(")content(DBI:driver:driverspecific)delimiter(")>operator(,) string<delimiter(")content(username)delimiter(")>operator(,) string<delimiter(")content(auth)delimiter(")>operator(\)) operator({)
+ operator(|)ident(dbh)operator(|)
+
+ ident(dbh)operator(.)ident(do)operator(()constant(SQL1)operator(\))
+
+ ident(dbh)operator(.)ident(prepare)operator(()constant(SQL2)operator(\))operator({) operator(|)ident(sth)operator(|)
+ ident(sth)operator(.)ident(execute)
+ ident(sth)operator(.)ident(fetch) operator({)operator(|)ident(row)operator(|)
+ comment(# ...)
+ operator(})
+ operator(}) comment(# end of block finishes the statement handle)
+ operator(}) comment(# end of block closes the database connection)
+reserved(rescue) constant(DBI)operator(::)constant(DatabaseError) operator(=)operator(>) ident(e)
+ ident(puts) string<delimiter(")content(dbi error occurred)delimiter(")>
+ ident(puts) string<delimiter(")content(Error code: )inline<delimiter(#{)ident(e)operator(.)ident(err)delimiter(})>delimiter(")>
+ ident(puts) string<delimiter(")content(Error message: )inline<delimiter(#{)ident(e)operator(.)ident(errstr)delimiter(})>delimiter(")>
+reserved(end)
+
+comment(#!/usr/bin/ruby -w)
+comment(# dbusers - example for mysql which creates a table,)
+comment(# fills it with values, retrieves the values back,)
+comment(# and finally destroys the table.)
+
+ident(require) string<delimiter(")content(dbi)delimiter(")>
+
+comment(# replacement for the User::pwnt module)
+reserved(def) method(getpwent)
+ ident(result) operator(=) operator([)operator(])
+ constant(File)operator(.)ident(open)operator(()string<delimiter(")content(/etc/passwd)delimiter(")>operator(\)) operator({)operator(|)ident(file)operator(|)
+ ident(file)operator(.)ident(each_line) operator({)operator(|)ident(line)operator(|)
+ reserved(next) reserved(if) ident(line)operator(.)ident(match)operator(()regexp<delimiter(/)content(^#)delimiter(/)>operator(\))
+ ident(cols) operator(=) ident(line)operator(.)ident(split)operator(()string<delimiter(")content(:)delimiter(")>operator(\))
+ ident(result)operator(.)ident(push)operator(()operator([)ident(cols)operator([)integer(2)operator(])operator(,) ident(cols)operator([)integer(0)operator(])operator(])operator(\))
+ operator(})
+ operator(})
+ ident(result)
+reserved(end)
+
+reserved(begin)
+ constant(DBI)operator(.)ident(connect)operator(()string<delimiter(")content(DBI:Mysql:pleacdatabase)delimiter(")>operator(,) string<delimiter(")content(pleac)delimiter(")>operator(,) string<delimiter(")content(pleacpassword)delimiter(")>operator(\)) operator({)
+ operator(|)ident(conn)operator(|)
+
+ ident(conn)operator(.)ident(do)operator(()string<delimiter(")content(CREATE TABLE users (uid INT, login CHAR(8\)\))delimiter(")>operator(\))
+
+ ident(users) operator(=) ident(getpwent)
+
+ ident(conn)operator(.)ident(prepare)operator(()string<delimiter(")content(INSERT INTO users VALUES (?,?\))delimiter(")>operator(\)) operator({)operator(|)ident(sth)operator(|)
+ ident(users)operator(.)ident(each) operator({)operator(|)ident(entry)operator(|)
+ ident(sth)operator(.)ident(execute)operator(()ident(entry)operator([)integer(0)operator(])operator(,) ident(entry)operator([)integer(1)operator(])operator(\))
+ operator(})
+ operator(})
+
+ ident(conn)operator(.)ident(execute)operator(()string<delimiter(")content(SELECT uid, login FROM users WHERE uid < 50)delimiter(")>operator(\)) operator({)operator(|)ident(sth)operator(|)
+ ident(sth)operator(.)ident(fetch) operator({)operator(|)ident(row)operator(|)
+ ident(puts) ident(row)operator(.)ident(collect) operator({)operator(|)ident(col)operator(|)
+ reserved(if) ident(col)operator(.)ident(nil?)
+ string<delimiter(")content((null\))delimiter(")>
+ reserved(else)
+ ident(col)
+ reserved(end)
+ operator(})operator(.)ident(join)operator(()string<delimiter(")content(, )delimiter(")>operator(\))
+ operator(})
+ operator(})
+
+ ident(conn)operator(.)ident(do)operator(()string<delimiter(")content(DROP TABLE users)delimiter(")>operator(\))
+ operator(})
+reserved(rescue) constant(DBI)operator(::)constant(DatabaseError) operator(=)operator(>) ident(e)
+ ident(puts) string<delimiter(")content(dbi error occurred)delimiter(")>
+ ident(puts) string<delimiter(")content(Error code: )inline<delimiter(#{)ident(e)operator(.)ident(err)delimiter(})>delimiter(")>
+ ident(puts) string<delimiter(")content(Error message: )inline<delimiter(#{)ident(e)operator(.)ident(errstr)delimiter(})>delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_15.1)
+comment(# This test program demonstrates parsing program arguments.)
+comment(# It uses the optparse library, which is included with ruby 1.8)
+comment(# It handles classic unix style and gnu style options)
+ident(require) string<delimiter(')content(optparse)delimiter(')>
+
+instance_variable(@debugmode) operator(=) pre_constant(false)
+instance_variable(@verbose) operator(=) pre_constant(false)
+
+pre_constant(ARGV)operator(.)ident(options) reserved(do) operator(|)ident(opts)operator(|)
+ ident(opts)operator(.)ident(banner) operator(=) string<delimiter(")content(Usage: ruby )inline<delimiter(#{)global_variable($0)delimiter(})>content( [OPTIONS] INPUTFILES)delimiter(")>
+
+ ident(opts)operator(.)ident(on)operator(()string<delimiter(")content(-h)delimiter(")>operator(,) string<delimiter(")content(--help)delimiter(")>operator(,) string<delimiter(")content(show this message)delimiter(")>operator(\)) operator({)
+ ident(puts) ident(opts)
+ ident(exit)
+ operator(})
+ comment(# The OptionParser#on method is called with a specification of short)
+ comment(# options, of long options, a data type spezification and user help)
+ comment(# messages for this option.)
+ comment(# The method analyses the given parameter and decides what it is,)
+ comment(# so you can leave out the long option if you don't need it)
+ ident(opts)operator(.)ident(on)operator(()string<delimiter(")content(-v)delimiter(")>operator(,) string<delimiter(")content(--[no-]verbose=[FLAG])delimiter(")>operator(,) constant(TrueClass)operator(,) string<delimiter(")content(run verbosly)delimiter(")>operator(\)) operator({)
+ operator(|)instance_variable(@verbose)operator(|) comment(# sets @verbose to true or false)
+ operator(})
+ ident(opts)operator(.)ident(on)operator(()string<delimiter(")content(-D)delimiter(")>operator(,) string<delimiter(")content(--DEBUG)delimiter(")>operator(,) constant(TrueClass)operator(,) string<delimiter(")content(turns on debug mode)delimiter(")> operator(\))operator({)
+ operator(|)instance_variable(@debugmode)operator(|) comment(# sets @debugmode to true)
+ operator(})
+ ident(opts)operator(.)ident(on)operator(()string<delimiter(")content(-c)delimiter(")>operator(,) string<delimiter(")content(--count=NUMBER)delimiter(")>operator(,) constant(Integer)operator(,) string<delimiter(")content(how many times we do it)delimiter(")> operator(\))operator({)
+ operator(|)instance_variable(@count)operator(|) comment(# sets @count to given integer)
+ operator(})
+ ident(opts)operator(.)ident(on)operator(()string<delimiter(")content(-o)delimiter(")>operator(,) string<delimiter(")content(--output=FILE)delimiter(")>operator(,) constant(String)operator(,) string<delimiter(")content(file to write output to)delimiter(")>operator(\))operator({)
+ operator(|)instance_variable(@outputfile)operator(|) comment(# sets @outputfile to given string)
+ operator(})
+ ident(opts)operator(.)ident(parse!)
+reserved(end)
+
+comment(# example to use the options in the main program)
+ident(puts) string<delimiter(")content(Verbose is on)delimiter(")> reserved(if) instance_variable(@verbose)
+ident(puts) string<delimiter(")content(Debugmode is on)delimiter(")> reserved(if) instance_variable(@debugmode)
+ident(puts) string<delimiter(")content(Outfile is )inline<delimiter(#{)instance_variable(@outputfile)delimiter(})>delimiter(")> reserved(if) reserved(defined?) instance_variable(@outputfile)
+ident(puts) string<delimiter(")content(Count is )inline<delimiter(#{)instance_variable(@count)delimiter(})>delimiter(")> reserved(if) reserved(defined?) instance_variable(@count)
+pre_constant(ARGV)operator(.)ident(each) operator({) operator(|)ident(param)operator(|)
+ ident(puts) string<delimiter(")content(Got parameter )inline<delimiter(#{)ident(param)delimiter(})>delimiter(")>
+operator(})
+
+
+comment(# @@PLEAC@@_15.4)
+ident(buf) operator(=) string<delimiter(")char(\\0)delimiter(")> operator(*) integer(8)
+global_variable($stdout)operator(.)ident(ioctl)operator(()integer(0x5413)operator(,) ident(buf)operator(\))
+ident(ws_row)operator(,) ident(ws_col)operator(,) ident(ws_xpixel)operator(,) ident(ws_ypixel) operator(=) ident(buf)operator(.)ident(unpack)operator(()string<delimiter(")content(S4)delimiter(")>operator(\))
+
+ident(raise) string<delimiter(")content(You must have at least 20 characters)delimiter(")> reserved(unless) ident(ws_col) operator(>)operator(=) integer(20)
+ident(max) operator(=) integer(0)
+ident(values) operator(=) operator(()integer(1)operator(..)integer(5)operator(\))operator(.)ident(collect) operator({) ident(rand)operator(()integer(20)operator(\)) operator(}) comment(# generate an array[5] of rand values)
+reserved(for) ident(i) reserved(in) ident(values)
+ ident(max) operator(=) ident(i) reserved(if) ident(max) operator(<) ident(i)
+reserved(end)
+ident(ratio) operator(=) constant(Float)operator(()ident(ws_col)operator(-)integer(12)operator(\))operator(/)ident(max) comment(# chars per unit)
+reserved(for) ident(i) reserved(in) ident(values)
+ ident(printf) string<delimiter(")content(%8.1f %s)char(\\n)delimiter(")>operator(,) ident(i)operator(,) string<delimiter(")content(*)delimiter(")> operator(*) operator(()ident(ratio)operator(*)ident(i)operator(\))
+reserved(end)
+
+comment(# gives, for example:)
+comment(# 15.0 *******************************)
+comment(# 10.0 *********************)
+comment(# 5.0 **********)
+comment(# 14.0 *****************************)
+comment(# 18.0 **************************************)
+
+
+comment(# @@PLEAC@@_16.1)
+ident(output) operator(=) shell<delimiter(`)content(program args)delimiter(`)> comment(# collect output into one multiline string)
+ident(output) operator(=) shell<delimiter(`)content(program args)delimiter(`)>operator(.)ident(split) comment(# collect output into array, one line per)
+ident(element)
+
+ident(readme) operator(=) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(ls)delimiter(")>operator(\))
+ident(output) operator(=) string<delimiter(")delimiter(")>
+reserved(while) ident(readme)operator(.)ident(gets) reserved(do)
+ ident(output) operator(+)operator(=) global_variable($_)
+reserved(end)
+ident(readme)operator(.)ident(close)
+
+shell<delimiter(`)content(fsck -y /dev/rsd1a)delimiter(`)> comment(# BAD AND SCARY in Perl because it's managed by the shell)
+ comment(# I donna in Ruby ...)
+
+comment(# so the "clean and secure" version)
+ident(readme)operator(,) ident(writeme) operator(=) constant(IO)operator(.)ident(pipe)
+ident(pid) operator(=) ident(fork) operator({)
+ comment(# child)
+ global_variable($stdout) operator(=) ident(writeme)
+ ident(readme)operator(.)ident(close)
+ ident(exec)operator(()string<delimiter(')content(find)delimiter(')>operator(,) string<delimiter(')content(..)delimiter(')>operator(\))
+operator(})
+comment(# parent)
+constant(Process)operator(.)ident(waitpid)operator(()ident(pid)operator(,) integer(0)operator(\))
+ident(writeme)operator(.)ident(close)
+reserved(while) ident(readme)operator(.)ident(gets) reserved(do)
+ comment(# do something with $_)
+reserved(end)
+
+
+comment(# @@PLEAC@@_16.2)
+ident(status) operator(=) ident(system)operator(()string<delimiter(")content(xemacs )inline<delimiter(#{)ident(myfile)delimiter(})>delimiter(")>operator(\))
+
+ident(status) operator(=) ident(system)operator(()string<delimiter(")content(xemacs)delimiter(")>operator(,) ident(myfile)operator(\))
+
+ident(system)operator(()string<delimiter(")content(cmd1 args | cmd2 | cmd3 >outfile)delimiter(")>operator(\))
+ident(system)operator(()string<delimiter(")content(cmd args <infile >outfile 2>errfile)delimiter(")>operator(\))
+
+comment(# stop if the command fails)
+ident(raise) string<delimiter(")content($program exited funny: )inline<delimiter(#{)global_variable($?)delimiter(})>delimiter(")> reserved(unless) ident(system)operator(()string<delimiter(")content(cmd)delimiter(")>operator(,) string<delimiter(")content(args1)delimiter(")>operator(,) string<delimiter(")content(args2)delimiter(")>operator(\))
+
+comment(# get the value of the signal sent to the child)
+comment(# even if it is a SIGINT or SIGQUIT)
+ident(system)operator(()ident(arglist)operator(\))
+ident(raise) string<delimiter(")content(program killed by signal )inline<delimiter(#{)global_variable($?)delimiter(})>delimiter(")> reserved(if) operator(()global_variable($?) operator(&) integer(127)operator(\)) operator(!)operator(=) integer(0)
+
+ident(pid) operator(=) ident(fork) operator({)
+ ident(trap)operator(()string<delimiter(")content(SIGINT)delimiter(")>operator(,) string<delimiter(")content(IGNORE)delimiter(")>operator(\))
+ ident(exec)operator(()string<delimiter(")content(sleep)delimiter(")>operator(,) string<delimiter(")content(10)delimiter(")>operator(\))
+operator(})
+ident(trap) operator(()string<delimiter(")content(SIGINT)delimiter(")>operator(\)) operator({)
+ ident(puts) string<delimiter(")content(Tsk tsk, no process interruptus)delimiter(")>
+operator(})
+constant(Process)operator(.)ident(waitpid)operator(()ident(pid)operator(,) integer(0)operator(\))
+
+comment(# Ruby doesn't permit to lie to the program called by a 'system'.)
+comment(# (ie specify what return argv[0] in C, $0 in Perl/Ruby ...\))
+comment(# A (dirty\) way is to create a link (under Unix\), run this link and)
+comment(# erase it. Somebody has a best idea ?)
+
+
+comment(# @@PLEAC@@_16.3)
+ident(exec)operator(()string<delimiter(")content(archive *.data)delimiter(")>operator(\))
+
+ident(exec)operator(()string<delimiter(")content(archive)delimiter(")>operator(,) string<delimiter(")content(accounting.data)delimiter(")>operator(\))
+
+ident(exec)operator(()string<delimiter(")content(archive accounting.data)delimiter(")>operator(\))
+
+
+comment(# @@PLEAC@@_16.4)
+comment(# read the output of a program)
+constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(ls)delimiter(")>operator(\)) operator({)operator(|)ident(readme)operator(|)
+ reserved(while) ident(readme)operator(.)ident(gets) reserved(do)
+ comment(# ...)
+ reserved(end)
+operator(})
+comment(# or)
+ident(readme) operator(=) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(ls)delimiter(")>operator(\))
+reserved(while) ident(readme)operator(.)ident(gets) reserved(do)
+ comment(# ...)
+reserved(end)
+ident(readme)operator(.)ident(close)
+
+comment(# "write" in a program)
+constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(cmd args)delimiter(")>operator(,)string<delimiter(")content(w)delimiter(")>operator(\)) operator({)operator(|)ident(pipe)operator(|)
+ ident(pipe)operator(.)ident(puts)operator(()string<delimiter(")content(data)delimiter(")>operator(\))
+ ident(pipe)operator(.)ident(puts)operator(()string<delimiter(")content(foo)delimiter(")>operator(\))
+operator(})
+
+comment(# close wait for the end of the process)
+ident(read) operator(=) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(sleep 10000)delimiter(")>operator(\)) comment(# child goes to sleep)
+ident(read)operator(.)ident(close) comment(# and the parent goes to lala land)
+
+ident(writeme) operator(=) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(cmd args)delimiter(")>operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+ident(writeme)operator(.)ident(puts) string<delimiter(")content(hello)delimiter(")> comment(# program will get hello\\n on STDIN)
+ident(writeme)operator(.)ident(close) comment(# program will get EOF on STDIN)
+
+comment(# send in a pager (eg less\) all output)
+global_variable($stdout) operator(=) constant(IO)operator(.)ident(popen)operator(()string<delimiter(")content(/usr/bin/less)delimiter(")>operator(,)string<delimiter(")content(w)delimiter(")>operator(\))
+ident(print) string<delimiter(")content(huge string)char(\\n)delimiter(")> operator(*) integer(10000)
+
+
+comment(# @@PLEAC@@_16.5)
+comment(#-----------------------------)
+reserved(def) method(head)operator(()ident(lines) operator(=) integer(20)operator(\))
+ ident(pid) operator(=) ident(open)operator(()string<delimiter(")content(|-)delimiter(")>operator(,)string<delimiter(")content(w)delimiter(")>operator(\))
+ reserved(if) ident(pid) operator(==) pre_constant(nil)
+ reserved(return)
+ reserved(else)
+ reserved(while) ident(gets)operator(()operator(\)) reserved(do)
+ ident(pid)operator(.)ident(print)
+ ident(lines) operator(-)operator(=) integer(1)
+ reserved(break) reserved(if) ident(lines) operator(==) integer(0)
+ reserved(end)
+ reserved(end)
+ ident(exit)
+reserved(end)
+
+ident(head)operator(()integer(100)operator(\))
+reserved(while) ident(gets)operator(()operator(\)) reserved(do)
+ ident(print)
+reserved(end)
+comment(#-----------------------------)
+integer(1)operator(:) operator(>) constant(Welcome) ident(to) constant(Linux)operator(,) ident(version) float(2.0)operator(.)integer(33) ident(on) ident(a) ident(i686)
+
+integer(2)operator(:) operator(>)
+
+integer(3)operator(:) operator(>) string<delimiter(")content(The software required `Windows 95 or better',
+
+4: > so I installed Linux.)delimiter(")>
+comment(#-----------------------------)
+operator(>) integer(1)operator(:) constant(Welcome) ident(to) constant(Linux)operator(,) constant(Kernel) ident(version) float(2.0)operator(.)integer(33) ident(on) ident(a) ident(i686)
+
+operator(>) integer(2)operator(:)
+
+operator(>) integer(3)operator(:) string<delimiter(")content(The software required `Windows 95 or better',
+
+> 4: so I installed Linux.)delimiter(")>
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby)
+comment(# qnumcat - demo additive output filters)
+
+reserved(def) method(number)operator(()operator(\))
+ ident(pid) operator(=) ident(open)operator(()string<delimiter(")content(|-)delimiter(")>operator(,)string<delimiter(")content(w)delimiter(")>operator(\))
+ reserved(if) ident(pid) operator(==) pre_constant(nil)
+ reserved(return)
+ reserved(else)
+ reserved(while) ident(gets)operator(()operator(\)) reserved(do) ident(pid)operator(.)ident(printf)operator(()string<delimiter(")content(%d: %s)delimiter(")>operator(,) global_variable($.)operator(,) global_variable($_)operator(\))operator(;) reserved(end)
+ reserved(end)
+ ident(exit)
+reserved(end)
+
+reserved(def) method(quote)operator(()operator(\))
+ ident(pid) operator(=) ident(open)operator(()string<delimiter(")content(|-)delimiter(")>operator(,)string<delimiter(")content(w)delimiter(")>operator(\))
+ reserved(if) ident(pid) operator(==) pre_constant(nil)
+ reserved(return)
+ reserved(else)
+ reserved(while) ident(gets)operator(()operator(\)) reserved(do) ident(pid)operator(.)ident(print) string<delimiter(")content(> )inline<delimiter(#{)global_variable($_)delimiter(})>delimiter(")> reserved(end)
+ reserved(end)
+ ident(exit)
+reserved(end)
+
+ident(number)operator(()operator(\))
+ident(quote)operator(()operator(\))
+
+reserved(while) ident(gets)operator(()operator(\)) reserved(do)
+ ident(print)
+reserved(end)
+global_variable($stdout)operator(.)ident(close)
+ident(exit)
+
+
+comment(# @@PLEAC@@_16.6)
+pre_constant(ARGV)operator(.)ident(map!) operator({) operator(|)ident(arg)operator(|)
+ ident(arg) operator(=)operator(~) regexp<delimiter(/)char(\\.)content((gz|Z\)$)delimiter(/)> operator(?) string<delimiter(")content(|gzip -dc )inline<delimiter(#{)ident(arg)delimiter(})>delimiter(")> operator(:) ident(arg)
+operator(})
+reserved(for) ident(file) reserved(in) pre_constant(ARGV)
+ ident(fh) operator(=) ident(open)operator(()ident(file)operator(\))
+ reserved(while) ident(fh)operator(.)ident(gets)operator(()operator(\)) reserved(do)
+ comment(# .......)
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+pre_constant(ARGV)operator(.)ident(map!) operator({) operator(|)ident(arg)operator(|)
+ ident(arg) operator(=)operator(~) regexp<delimiter(%r#)content(^)char(\\w)content(+://)delimiter(#)> operator(?) string<delimiter(")content(|GET )inline<delimiter(#{)ident(arg)delimiter(})>delimiter(")> operator(:) ident(arg) comment(#)
+operator(})
+reserved(for) ident(file) reserved(in) pre_constant(ARGV)
+ ident(fh) operator(=) ident(open)operator(()ident(file)operator(\))
+ reserved(while) ident(fh)operator(.)ident(gets)operator(()operator(\)) reserved(do)
+ comment(# .......)
+ reserved(end)
+reserved(end)
+comment(#-----------------------------)
+ident(pwdinfo) operator(=) operator(()shell<delimiter(`)content(domainname)delimiter(`)> operator(=)operator(~) regexp<delimiter(/)content(^()char(\\()content(none)char(\\\))content(\)?$)delimiter(/)>operator(\)) operator(?) string<delimiter(')content(/etc/passwd)delimiter(')> operator(:) string<delimiter(')content(|ypcat passwd)delimiter(')>operator(;)
+ident(pwd) operator(=) ident(open)operator(()ident(pwdinfo)operator(\))operator(;)
+comment(#-----------------------------)
+ident(puts) string<delimiter(")content(File, please? )delimiter(")>operator(;)
+ident(file) operator(=) ident(gets)operator(()operator(\))operator(.)ident(chomp)operator(()operator(\))operator(;)
+ident(fh) operator(=) ident(open)operator(()ident(file)operator(\))operator(;)
+
+
+comment(# @@PLEAC@@_16.7)
+ident(output) operator(=) shell<delimiter(`)content(cmd 2>&1)delimiter(`)> comment(# with backticks)
+comment(# or)
+ident(ph) operator(=) ident(open)operator(()string<delimiter(")content(|cmd 2>&1)delimiter(")>operator(\)) comment(# with an open pipe)
+reserved(while) ident(ph)operator(.)ident(gets)operator(()operator(\)) operator({) operator(}) comment(# plus a read)
+comment(#-----------------------------)
+ident(output) operator(=) shell<delimiter(`)content(cmd 2>/dev/null)delimiter(`)> comment(# with backticks)
+comment(# or)
+ident(ph) operator(=) ident(open)operator(()string<delimiter(")content(|cmd 2>/dev/null)delimiter(")>operator(\)) comment(# with an open pipe)
+reserved(while) ident(ph)operator(.)ident(gets)operator(()operator(\)) operator({) operator(}) comment(# plus a read)
+comment(#-----------------------------)
+ident(output) operator(=) shell<delimiter(`)content(cmd 2>&1 1>/dev/null)delimiter(`)> comment(# with backticks)
+comment(# or)
+ident(ph) operator(=) ident(open)operator(()string<delimiter(")content(|cmd 2>&1 1>/dev/null)delimiter(")>operator(\)) comment(# with an open pipe)
+reserved(while) ident(ph)operator(.)ident(gets)operator(()operator(\)) operator({) operator(}) comment(# plus a read)
+comment(#-----------------------------)
+ident(output) operator(=) shell<delimiter(`)content(cmd 3>&1 1>&2 2>&3 3>&-)delimiter(`)> comment(# with backticks)
+comment(# or)
+ident(ph) operator(=) ident(open)operator(()string<delimiter(")content(|cmd 3>&1 1>&2 2>&3 3>&-)delimiter(")>operator(\)) comment(# with an open pipe)
+reserved(while) ident(ph)operator(.)ident(gets)operator(()operator(\)) operator({) operator(}) comment(# plus a read)
+comment(#-----------------------------)
+ident(system)operator(()string<delimiter(")content(program args 1>/tmp/program.stdout 2>/tmp/program.stderr)delimiter(")>operator(\))
+comment(#-----------------------------)
+ident(output) operator(=) shell<delimiter(`)content(cmd 3>&1 1>&2 2>&3 3>&-)delimiter(`)>
+comment(#-----------------------------)
+ident(fd3) operator(=) ident(fd1)
+ident(fd1) operator(=) ident(fd2)
+ident(fd2) operator(=) ident(fd3)
+ident(fd3) operator(=) pre_constant(nil)
+comment(#-----------------------------)
+ident(system)operator(()string<delimiter(")content(prog args 1>tmpfile 2>&1)delimiter(")>operator(\))
+ident(system)operator(()string<delimiter(")content(prog args 2>&1 1>tmpfile)delimiter(")>operator(\))
+comment(#-----------------------------)
+comment(# system ("prog args 1>tmpfile 2>&1"\) )
+ident(fd1) operator(=) string<delimiter(")content(tmpfile)delimiter(")> comment(# change stdout destination first)
+ident(fd2) operator(=) ident(fd1) comment(# now point stderr there, too)
+comment(#-----------------------------)
+comment(# system("prog args 2>&1 1>tmpfile"\) )
+ident(fd2) operator(=) ident(fd1) comment(# stderr same destination as stdout)
+ident(fd1) operator(=) string<delimiter(")content(tmpfile)delimiter(")> comment(# but change stdout destination )
+comment(#-----------------------------)
+comment(# It is often better not to rely on the shell, )
+comment(# because of portability, possible security problems )
+comment(# and bigger resource usage. So, it is often better to use the open3 library. )
+comment(# See below for an example.)
+comment(# opening stdin, stdout, stderr)
+ident(require) string<delimiter(")content(open3)delimiter(")>
+ident(stdin)operator(,) ident(stdout)operator(,) ident(stderr) operator(=) constant(Open3)operator(.)ident(popen)operator(()string<delimiter(')content(cmd)delimiter(')>operator(\))
+
+
+comment(# @@PLEAC@@_16.8)
+comment(#-----------------------------)
+comment(# Contrary to perl, we don't need to use a module in Ruby)
+ident(fh) operator(=) constant(Kernel)operator(.)ident(open)operator(()string<delimiter(")content(|)delimiter(")> operator(+) ident(program)operator(,) string<delimiter(")content(w+)delimiter(")>operator(\))
+ident(fh)operator(.)ident(puts) string<delimiter(")content(here's your input)char(\\n)delimiter(")>
+ident(output) operator(=) ident(fh)operator(.)ident(gets)operator(()operator(\))
+ident(fh)operator(.)ident(close)operator(()operator(\))
+comment(#-----------------------------)
+constant(Kernel)operator(.)ident(open)operator(()string<delimiter(")content(|program)delimiter(")>operator(\))operator(,)string<delimiter(")content(w+)delimiter(")>operator(\)) comment(# RIGHT !)
+comment(#-----------------------------)
+comment(# Ruby has already object methods for I/O handles)
+comment(#-----------------------------)
+reserved(begin)
+ ident(fh) operator(=) constant(Kernel)operator(.)ident(open)operator(()string<delimiter(")content(|)delimiter(")> operator(+) ident(program_and_options)operator(,) string<delimiter(")content(w+)delimiter(")>operator(\))
+reserved(rescue)
+ reserved(if) operator(()global_variable($@) operator(~)operator(=) regexp<delimiter(/)content(^open)delimiter(/)>operator(\))
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(open failed : )inline<delimiter(#{)global_variable($!)delimiter(})>content( )char(\\n)content( )inline<delimiter(#{)global_variable($@)delimiter(})>content( )char(\\n)delimiter(")>
+ reserved(break)
+ reserved(end)
+ ident(raise) comment(# reraise unforseen exception)
+reserved(end)
+
+
+comment(# @@PLEAC@@_16.13)
+comment(#% kill -l)
+comment(#HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE)
+comment(#ALRM TERM CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM)
+comment(#PROF WINCH POLL PWR)
+comment(#-----------------------------)
+comment(#% ruby -e 'puts Signal.list.keys.join(" "\)')
+comment(#PWR USR1 BUS USR2 TERM SEGV KILL POLL STOP SYS TRAP IOT HUP INT #)
+comment(#WINCH XCPU TTIN CLD TSTP FPE IO TTOU PROF CHLD CONT PIPE ABRT)
+comment(#VTALRM QUIT ILL XFSZ URG ALRM)
+comment(#-----------------------------)
+comment(# After that, the perl script create an hash equivalent to Signal.list, )
+comment(# and an array. The array can be obtained by :)
+ident(signame) operator(=) operator([)operator(])
+constant(Signal)operator(.)ident(list)operator(.)ident(each) operator({) operator(|)ident(name)operator(,) ident(i)operator(|) ident(signame)operator([)ident(i)operator(]) operator(=) ident(name) operator(})
+
+
+comment(# @@PLEAC@@_16.14)
+constant(Process)operator(.)ident(kill)operator(()integer(9)operator(,) ident(pid)operator(\)) comment(# send $pid a signal 9)
+constant(Process)operator(.)ident(kill)operator(()operator(-)integer(1)operator(,) constant(Process)operator(.)ident(getpgrp)operator(()operator(\))operator(\)) comment(# send whole job a signal 1)
+constant(Process)operator(.)ident(kill)operator(()string<delimiter(")content(USR1)delimiter(")>operator(,) global_variable($$)operator(\)) comment(# send myself a SIGUSR1)
+constant(Process)operator(.)ident(kill)operator(()string<delimiter(")content(HUP)delimiter(")>operator(,) ident(pid1)operator(,) ident(pid2)operator(,) ident(pid3)operator(\)) comment(# send a SIGHUP to processes in @pids)
+comment(#-----------------------------)
+reserved(begin)
+ constant(Process)operator(.)ident(kill)operator(()integer(0)operator(,) ident(minion)operator(\))
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(minion)delimiter(})>content( is alive!)delimiter(")>
+reserved(rescue) constant(Errno)operator(::)constant(EPERM) comment(# changed uid)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(minion)delimiter(})>content( has escaped my control!)delimiter(")>operator(;)
+reserved(rescue) constant(Errno)operator(::)constant(ESRCH)
+ ident(puts) string<delimiter(")inline<delimiter(#{)ident(minion)delimiter(})>content( is deceased.)delimiter(")>operator(;) comment(# or zombied)
+reserved(rescue)
+ ident(puts) string<delimiter(")content(Odd; I couldn't check the status of )inline<delimiter(#{)ident(minion)delimiter(})>content( : )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_16.15)
+constant(Kernel)operator(.)ident(trap)operator(()string<delimiter(")content(QUIT)delimiter(")>operator(,) ident(got_sig_quit)operator(\)) comment(# got_sig_quit = Proc.new { puts "Quit\\n" })
+ident(trap)operator(()string<delimiter(")content(PIPE)delimiter(")>operator(,) string<delimiter(")content(got_sig_quit)delimiter(")>operator(\)) comment(# def got_sig_pipe ...)
+ident(trap)operator(()string<delimiter(")content(INT)delimiter(")>operator(\)) operator({) ident(ouch)operator(+)operator(+) operator(}) comment(# increment ouch for every SIGINT)
+comment(#-----------------------------)
+ident(trap)operator(()string<delimiter(")content(INT)delimiter(")>operator(,) string<delimiter(")content(IGNORE)delimiter(")>operator(\)) comment(# ignore the signal INT)
+comment(#-----------------------------)
+ident(trap)operator(()string<delimiter(")content(STOP)delimiter(")>operator(,) string<delimiter(")content(DEFAULT)delimiter(")>operator(\)) comment(# restore default STOP signal handling)
+
+
+comment(# @@PLEAC@@_16.16)
+comment(# the signal handler)
+reserved(def) method(ding)
+ ident(trap)operator(()string<delimiter(")content(INT)delimiter(")>operator(,) string<delimiter(")content(ding)delimiter(")>operator(\))
+ ident(puts) string<delimiter(")char(\\a)content(Enter your name!)delimiter(")>
+reserved(end)
+
+comment(# prompt for name, overriding SIGINT)
+reserved(def) method(get_name)
+ ident(save) operator(=) ident(trap)operator(()string<delimiter(")content(INT)delimiter(")>operator(,) string<delimiter(")content(ding)delimiter(")>operator(\))
+
+ ident(puts) string<delimiter(")content(Kindly Stranger, please enter your name: )delimiter(")>
+ ident(name) operator(=) ident(gets)operator(()operator(\))operator(.)ident(chomp)operator(()operator(\))
+ ident(trap)operator(()string<delimiter(")content(INT)delimiter(")>operator(,) ident(save)operator(\))
+ ident(name)
+reserved(end)
+
+
+comment(# @@PLEAC@@_16.21)
+comment(# implemented thanks to http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/1760)
+ident(require) string<delimiter(')content(timeout)delimiter(')>
+
+comment(# we'll do something vastly more useful than cookbook to demonstrate timeouts)
+reserved(begin)
+ ident(timeout)operator(()integer(5)operator(\)) operator({)
+ ident(waitsec) operator(=) ident(rand)operator(()integer(10)operator(\))
+ ident(puts) string<delimiter(")content(Let's see if a sleep of )inline<delimiter(#{)ident(waitsec)delimiter(})>content( seconds is longer than 5 seconds...)delimiter(")>
+ ident(system)operator(()string<delimiter(")content(sleep )inline<delimiter(#{)ident(waitsec)delimiter(})>delimiter(")>operator(\))
+ operator(})
+ ident(puts) string<delimiter(")content(Timeout didn't occur)delimiter(")>
+reserved(rescue) constant(Timeout)operator(::)constant(Error)
+ ident(puts) string<delimiter(")content(Timed out!)delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_17.1)
+comment(# A basic TCP client connection)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+reserved(begin)
+ ident(t) operator(=) constant(TCPSocket)operator(.)ident(new)operator(()string<delimiter(')content(www.ruby-lang.org)delimiter(')>operator(,) string<delimiter(')content(www)delimiter(')>operator(\))
+reserved(rescue)
+ ident(puts) string<delimiter(")content(error: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(else)
+ comment(# ... do something with the socket)
+ ident(t)operator(.)ident(print) string<delimiter(")content(GET / HTTP/1.0)char(\\n)char(\\n)delimiter(")>
+ ident(answer) operator(=) ident(t)operator(.)ident(gets)operator(()pre_constant(nil)operator(\))
+ comment(# and terminate the connection when we're done)
+ ident(t)operator(.)ident(close)
+reserved(end)
+
+comment(# Using the evil low level socket API)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+comment(# create a socket)
+ident(s) operator(=) constant(Socket)operator(.)ident(new)operator(()constant(Socket)operator(::)constant(AF_INET)operator(,) constant(Socket)operator(::)constant(SOCK_STREAM)operator(,) integer(0)operator(\))
+comment(# build the address of the remote machine)
+ident(sockaddr_server) operator(=) operator([)constant(Socket)operator(::)constant(AF_INET)operator(,) integer(80)operator(,)
+ constant(Socket)operator(.)ident(gethostbyname)operator(()string<delimiter(')content(www.ruby-lang.org)delimiter(')>operator(\))operator([)integer(3)operator(])operator(,)
+ integer(0)operator(,) integer(0)operator(])operator(.)ident(pack)operator(()string<delimiter(")content(snA4NN)delimiter(")>operator(\))
+comment(# connect)
+reserved(begin)
+ ident(s)operator(.)ident(connect)operator(()ident(sockaddr_server)operator(\))
+reserved(rescue)
+ ident(puts) string<delimiter(")content(error: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(else)
+ comment(# ... do something with the socket)
+ ident(s)operator(.)ident(print) string<delimiter(")content(GET / HTTP/1.0)char(\\n)char(\\n)delimiter(")>
+ comment(# and terminate the connection when we're done)
+ ident(s)operator(.)ident(close)
+reserved(end)
+
+comment(# TCP connection with management of error (DNS\))
+ident(require) string<delimiter(')content(socket)delimiter(')>
+reserved(begin)
+ ident(client) operator(=) constant(TCPSocket)operator(.)ident(new)operator(()string<delimiter(')content(does not exists)delimiter(')>operator(,) string<delimiter(')content(www)delimiter(')>operator(\))
+reserved(rescue)
+ ident(puts) string<delimiter(")content(error: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(end)
+
+comment(# TCP connection with a time out)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+ident(require) string<delimiter(')content(timeout)delimiter(')>
+reserved(begin)
+ ident(timeout)operator(()integer(1)operator(\)) reserved(do) comment(#the server has one second to answer)
+ ident(client) operator(=) constant(TCPSocket)operator(.)ident(new)operator(()string<delimiter(')content(www.host.com)delimiter(')>operator(,) string<delimiter(')content(www)delimiter(')>operator(\))
+ reserved(end)
+reserved(rescue)
+ ident(puts) string<delimiter(")content(error: )inline<delimiter(#{)global_variable($!)delimiter(})>delimiter(")>
+reserved(end)
+
+
+comment(# @@PLEAC@@_17.12)
+ident(require) string<delimiter(')content(socket)delimiter(')>
+
+reserved(class) class(Preforker)
+ ident(attr_reader) operator(()symbol(:child_count)operator(\))
+
+ reserved(def) method(initialize)operator(()ident(prefork)operator(,) ident(max_clients_per_child)operator(,) ident(port)operator(,) ident(client_handler)operator(\))
+ instance_variable(@prefork) operator(=) ident(prefork)
+ instance_variable(@max_clients_per_child) operator(=) ident(max_clients_per_child)
+ instance_variable(@port) operator(=) ident(port)
+ instance_variable(@child_count) operator(=) integer(0)
+
+ instance_variable(@reaper) operator(=) ident(proc) operator({)
+ ident(trap)operator(()string<delimiter(')content(CHLD)delimiter(')>operator(,) instance_variable(@reaper)operator(\))
+ ident(pid) operator(=) constant(Process)operator(.)ident(wait)
+ instance_variable(@child_count) operator(-)operator(=) integer(1)
+ operator(})
+
+ instance_variable(@huntsman) operator(=) ident(proc) operator({)
+ ident(trap)operator(()string<delimiter(')content(CHLD)delimiter(')>operator(,) string<delimiter(')content(IGNORE)delimiter(')>operator(\))
+ ident(trap)operator(()string<delimiter(')content(INT)delimiter(')>operator(,) string<delimiter(')content(IGNORE)delimiter(')>operator(\))
+ constant(Process)operator(.)ident(kill)operator(()string<delimiter(')content(INT)delimiter(')>operator(,) integer(0)operator(\))
+ ident(exit)
+ operator(})
+
+ instance_variable(@client_handler)operator(=)ident(client_handler)
+ reserved(end)
+
+ reserved(def) method(child_handler)
+ ident(trap)operator(()string<delimiter(')content(INT)delimiter(')>operator(,) string<delimiter(')content(EXIT)delimiter(')>operator(\))
+ instance_variable(@client_handler)operator(.)ident(setUp)
+ comment(# wish: sigprocmask UNblock SIGINT)
+ instance_variable(@max_clients_per_child)operator(.)ident(times) operator({)
+ ident(client) operator(=) instance_variable(@server)operator(.)ident(accept) reserved(or) reserved(break)
+ instance_variable(@client_handler)operator(.)ident(handle_request)operator(()ident(client)operator(\))
+ ident(client)operator(.)ident(close)
+ operator(})
+ instance_variable(@client_handler)operator(.)ident(tearDown)
+ reserved(end)
+
+ reserved(def) method(make_new_child)
+ comment(# wish: sigprocmask block SIGINT)
+ instance_variable(@child_count) operator(+)operator(=) integer(1)
+ ident(pid) operator(=) ident(fork) reserved(do)
+ ident(child_handler)
+ reserved(end)
+ comment(# wish: sigprocmask UNblock SIGINT)
+ reserved(end)
+
+ reserved(def) method(run)
+ instance_variable(@server) operator(=) constant(TCPserver)operator(.)ident(open)operator(()instance_variable(@port)operator(\))
+ ident(trap)operator(()string<delimiter(')content(CHLD)delimiter(')>operator(,) instance_variable(@reaper)operator(\))
+ ident(trap)operator(()string<delimiter(')content(INT)delimiter(')>operator(,) instance_variable(@huntsman)operator(\))
+ ident(loop) operator({)
+ operator(()instance_variable(@prefork) operator(-) instance_variable(@child_count)operator(\))operator(.)ident(times) operator({) operator(|)ident(i)operator(|)
+ ident(make_new_child)
+ operator(})
+ ident(sleep) operator(.)integer(1)
+ operator(})
+ reserved(end)
+reserved(end)
+
+comment(#-----------------------------)
+comment(#!/usr/bin/ruby)
+
+ident(require) string<delimiter(')content(Preforker)delimiter(')>
+
+reserved(class) class(ClientHandler)
+ reserved(def) method(setUp)
+ reserved(end)
+
+ reserved(def) method(tearDown)
+ reserved(end)
+
+ reserved(def) method(handle_request)operator(()ident(client)operator(\))
+ comment(# do stuff)
+ reserved(end)
+reserved(end)
+
+ident(server) operator(=) constant(Preforker)operator(.)ident(new)operator(()integer(1)operator(,) integer(100)operator(,) integer(3102)operator(,) constant(ClientHandler)operator(.)ident(new)operator(\))
+ident(server)operator(.)ident(run)
+
+
+comment(# @@PLEAC@@_18.2)
+ident(require) string<delimiter(')content(net/ftp)delimiter(')>
+
+reserved(begin)
+ ident(ftp) operator(=) constant(Net)operator(::)constant(FTP)operator(::)ident(new)operator(()string<delimiter(")content(ftp.host.com)delimiter(")>operator(\))
+ ident(ftp)operator(.)ident(login)operator(()ident(username)operator(,)ident(password)operator(\))
+ ident(ftp)operator(.)ident(chdir)operator(()ident(directory)operator(\))
+ ident(ftp)operator(.)ident(get)operator(()ident(filename)operator(\))
+ ident(ftp)operator(.)ident(put)operator(()ident(filename)operator(\))
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(print) string<delimiter(")content(FTP failed: )delimiter(")> operator(+) global_variable($!)
+reserved(ensure)
+ ident(ftp)operator(.)ident(close)operator(()operator(\)) reserved(if) ident(ftp)
+reserved(end)
+
+comment(# A better solution for a local use could be :)
+constant(Net)operator(::)constant(FTP)operator(::)ident(new)operator(()string<delimiter(")content(ftp.host.com)delimiter(")>operator(\)) reserved(do) operator(|)ident(ftp)operator(|)
+ ident(ftp)operator(.)ident(login)operator(()ident(username)operator(,)ident(password)operator(\))
+ ident(ftp)operator(.)ident(chdir)operator(()ident(directory)operator(\))
+ ident(ftp)operator(.)ident(get)operator(()ident(filename)operator(\))
+ ident(ftp)operator(.)ident(put)operator(()ident(filename)operator(\))
+reserved(end)
+
+comment(# If you have only one file to get, there is a simple solution :)
+ident(require) string<delimiter(')content(open-uri)delimiter(')>
+ident(open)operator(()string<delimiter(")content(ftp://www.ruby-lang.org/path/filename)delimiter(")>operator(\)) reserved(do) operator(|)ident(fh)operator(|)
+ comment(# read from filehandle fh)
+reserved(end)
+comment(#--------------------------------------------)
+comment(# to wait a defined time for the connection, )
+comment(# use the timeout module)
+ident(require) string<delimiter(')content(timeout)delimiter(')>
+reserved(begin)
+ ident(timeout)operator(()integer(30)operator(\))operator({)
+ ident(ftp) operator(=) constant(Net)operator(::)constant(FTP)operator(::)ident(new)operator(()string<delimiter(")content(ftp.host.com)delimiter(")>operator(\))
+ ident(ftp)operator(.)ident(debug_mode) operator(=) pre_constant(true)
+ operator(})
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(Couldn't connect.)delimiter(")>
+reserved(rescue) constant(Timeout)operator(::)constant(Error)
+ global_variable($stderr)operator(.)ident(puts) string<delimiter(")content(Timeout while connecting to server.)delimiter(")>
+reserved(end)
+
+reserved(begin)
+ ident(ftp)operator(.)ident(login)operator(()operator(\))
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(print) string<delimiter(")content(Couldn't authentificate.)char(\\n)delimiter(")>
+reserved(end)
+
+reserved(begin)
+ ident(ftp)operator(.)ident(login)operator(()ident(username)operator(\))
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(print) string<delimiter(")content(Still couldn't authenticate.)char(\\n)delimiter(")>
+reserved(end)
+
+reserved(begin)
+ ident(ftp)operator(.)ident(login)operator(()ident(username)operator(,) ident(password)operator(\))
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(print) string<delimiter(")content(Couldn't authenticate, even with explicit
+ username and password.)char(\\n)delimiter(")>
+reserved(end)
+
+reserved(begin)
+ ident(ftp)operator(.)ident(login)operator(()ident(username)operator(,) ident(password)operator(,) ident(account)operator(\))
+reserved(rescue) constant(Net)operator(::)constant(FTPError)
+ global_variable($stderr)operator(.)ident(print) string<delimiter(")content(No dice. It hates me.)char(\\n)delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(put)operator(()ident(localfile)operator(,) ident(remotefile)operator(\))
+comment(#-----------------------------)
+comment(# Sending data from STDIN is not directly supported )
+comment(# by the ftp library module. A possible way to do it is to use the )
+comment(# storlines method directly to send raw commands to the ftp server.)
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(get)operator(()ident(remotefile)operator(,) ident(localfile)operator(\))
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(get)operator(()ident(remotefile)operator(\)) operator({) operator(|)ident(data)operator(|) ident(puts) ident(data) operator(})
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(chdir)operator(()string<delimiter(")content(/pub/ruby)delimiter(")>operator(\))
+ident(print) string<delimiter(")content(I'm in the directory )delimiter(")>operator(,) ident(ftp)operator(.)ident(pwd)operator(()operator(\))operator(,) string<delimiter(")char(\\n)delimiter(")>
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(mkdir)operator(()string<delimiter(")content(/pub/ruby/new_dir)delimiter(")>operator(\))
+comment(#-----------------------------)
+ident(lines) operator(=) ident(ftp)operator(.)ident(ls)operator(()string<delimiter(")content(/pub/ruby/)delimiter(")>operator(\))
+comment(# => ["drwxr-xr-x 2 matz users 4096 July 17 1998 1.0", ... ])
+
+ident(latest) operator(=) ident(ftp)operator(.)ident(dir)operator(()string<delimiter(")content(/pub/ruby/*.tgz)delimiter(")>operator(\))operator(.)ident(sort)operator(.)ident(last)
+
+ident(ftp)operator(.)ident(nlst)operator(()string<delimiter(")content(/pub/ruby)delimiter(")>operator(\))
+comment(# => ["/pub/ruby/1.0", ... ])
+comment(#-----------------------------)
+ident(ftp)operator(.)ident(quit)operator(()operator(\))
+
+
+comment(# @@PLEAC@@_18.6)
+ident(require) string<delimiter(')content(net/telnet)delimiter(')>
+ident(t) operator(=) constant(Net)operator(::)constant(Telnet)operator(::)ident(new)operator(() string<delimiter(")content(Timeout)delimiter(")> operator(=)operator(>) integer(10)operator(,)
+ string<delimiter(")content(Prompt)delimiter(")> operator(=)operator(>) regexp<delimiter(/)content(%)delimiter(/)>operator(,)
+ string<delimiter(")content(Host)delimiter(")> operator(=)operator(>) ident(host) operator(\))
+ident(t)operator(.)ident(login)operator(()ident(username)operator(,) ident(password)operator(\))
+ident(files) operator(=) ident(t)operator(.)ident(cmd)operator(()string<delimiter(")content(ls)delimiter(")>operator(\))
+ident(t)operator(.)ident(print)operator(()string<delimiter(")content(top)delimiter(")>operator(\))
+ident(process_string) operator(=) ident(t)operator(.)ident(waitfor)operator(()regexp<delimiter(/)char(\\d)content(+ processes)delimiter(/)>operator(\))
+ident(t)operator(.)ident(close)
+comment(#-----------------------------)
+regexp<delimiter(/)content([$%#>] )char(\\z)delimiter(/)modifier(n)>
+comment(#-----------------------------)
+comment(# In case of an error, the telnet module throws an exception.)
+comment(# For control of the behavior in case of an error,)
+comment(# you just need to catch the exceptions and do your custom)
+comment(# error handling.)
+comment(#-----------------------------)
+reserved(begin)
+ ident(telnet)operator(.)ident(login)operator(()ident(username)operator(,) ident(password)operator(\))
+reserved(rescue) constant(TimeoutError)
+ ident(fail) string<delimiter(")content(Login failed !)char(\\n)delimiter(")>
+reserved(end)
+comment(#-----------------------------)
+ident(telnet)operator(.)ident(waitfor)operator(()string<delimiter(')content(/--more--/)delimiter(')>operator(\))
+comment(#-----------------------------)
+ident(telnet)operator(.)ident(waitfor)operator(()constant(String) operator(=)operator(>) string<delimiter(')content(greasy smoke)delimiter(')>operator(,) constant(Timeout) operator(=)operator(>) integer(30)operator(\))
+
+
+comment(# @@PLEAC@@_18.7)
+ident(require) string<delimiter(')content(ping)delimiter(')>
+
+ident(puts) string<delimiter(")inline<delimiter(#{)ident(host)delimiter(})>content( is alive.)char(\\n)delimiter(")> reserved(if) constant(Ping)operator(.)ident(pingecho)operator(()ident(host)operator(\))operator(;)
+comment(#-----------------------------)
+comment(# the ping module only use TCP ping, not ICMP even if we are root)
+reserved(if) constant(Ping)operator(.)ident(pingecho)operator(()string<delimiter(")content(kingkong.com)delimiter(")>operator(\))
+ ident(puts) string<delimiter(")content(The giant ape lives!)char(\\n)delimiter(")>operator(;)
+reserved(else)
+ ident(puts) string<delimiter(")content(All hail mighty Gamera, friend of children!)char(\\n)delimiter(")>operator(;)
+reserved(end)
+
+
+comment(# @@PLEAC@@_19.0)
+comment(#-----------------------------)
+comment(# http://www.perl.com/CPAN/)
+comment(# http://www.perl.com:8001/bad/mojo.html)
+comment(# ftp://gatekeeper.dec.com/pub/misc/netlib.tar.Z)
+comment(# ftp://anonymous@myplace:gatekeeper.dec.com/pub/misc/netlib.tar.Z)
+comment(# file:///etc/motd)
+comment(#-----------------------------)
+comment(# http://mox.perl.com/cgi-bin/program?name=Johann&born=1685)
+comment(#-----------------------------)
+comment(# http://mox.perl.com/cgi-bin/program)
+comment(#-----------------------------)
+
+
+comment(# @@PLEAC@@_19.1)
+comment(#!/usr/local/bin/ruby -w)
+comment(# hiweb - load CGI class to decode information given by web server)
+
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+
+ident(cgi) operator(=) constant(CGI)operator(.)ident(new)operator(()string<delimiter(')content(html3)delimiter(')>operator(\))
+
+comment(# get a parameter from a form)
+ident(value) operator(=) ident(cgi)operator(.)ident(params)operator([)string<delimiter(')content(PARAM_NAME)delimiter(')>operator(])operator([)integer(0)operator(])
+
+comment(# output a document)
+ident(cgi)operator(.)ident(out) operator({)
+ ident(cgi)operator(.)ident(html) operator({)
+ ident(cgi)operator(.)ident(head) operator({) ident(cgi)operator(.)ident(title) operator({) string<delimiter(")content(Howdy there!)delimiter(")> operator(}) operator(}) operator(+)
+ ident(cgi)operator(.)ident(body) operator({) ident(cgi)operator(.)ident(p) operator({) string<delimiter(")content(You typed: )delimiter(")> operator(+) ident(cgi)operator(.)ident(tt) operator({)
+ constant(CGI)operator(.)ident(escapeHTML)operator(()ident(value)operator(\)) operator(}) operator(}) operator(})
+ operator(})
+operator(})
+
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+ident(cgi) operator(=) constant(CGI)operator(.)ident(new)
+ident(who) operator(=) ident(cgi)operator(.)ident(param)operator([)string<delimiter(")content(Name)delimiter(")>operator(])operator([)integer(0)operator(]) comment(# first param in list)
+ident(phone) operator(=) ident(cgi)operator(.)ident(param)operator([)string<delimiter(")content(Number)delimiter(")>operator(])operator([)integer(0)operator(])
+ident(picks) operator(=) ident(cgi)operator(.)ident(param)operator([)string<delimiter(")content(Choices)delimiter(")>operator(]) comment(# complete list)
+
+ident(print) ident(cgi)operator(.)ident(header)operator(() string<delimiter(')content(type)delimiter(')> operator(=)operator(>) string<delimiter(')content(text/plain)delimiter(')>operator(,)
+ string<delimiter(')content(expires)delimiter(')> operator(=)operator(>) constant(Time)operator(.)ident(now) operator(+) operator(()integer(3) operator(*) integer(24) operator(*) integer(60) operator(*) integer(60)operator(\)) operator(\))
+
+
+comment(# @@PLEAC@@_19.3)
+comment(#!/usr/local/bin/ruby -w)
+comment(# webwhoami - show web user's id)
+ident(require) string<delimiter(')content(etc)delimiter(')>
+ident(print) string<delimiter(")content(Content-Type: text/plain)char(\\n)char(\\n)delimiter(")>
+ident(print) string<delimiter(")content(Running as )delimiter(")> operator(+) constant(Etc)operator(.)ident(getpwuid)operator(.)ident(name) operator(+) string<delimiter(")char(\\n)delimiter(")>
+
+comment(# % ruby -wc cgi-script # just check syntax)
+
+comment(# % ruby -w cgi-script # params from stdin)
+comment(# (offline mode: enter name=value pairs on standard input\))
+comment(# name=joe)
+comment(# number=10)
+comment(# ^D)
+
+comment(# % ruby -w cgi-script name=joe number=10 # run with mock form input)
+comment(# % ruby -d cgi-script name=joe number=10 # ditto, under the debugger)
+
+comment(# POST method script in csh)
+comment(# % (setenv HTTP_METHOD POST; ruby -w cgi-script name=joe number=10\))
+comment(# POST method script in sh)
+comment(# % HTTP_METHOD=POST perl -w cgi-script name=joe number=10)
+
+
+comment(# @@PLEAC@@_19.4)
+comment(# ruby has several security levels, the level "1" is similar to perls taint mode.)
+comment(# It can be switched on by providing the -T command line parameter)
+comment(# or by setting $SAFE to 1. Setting $SAFE to 2,3 or 4 restricts possible)
+comment(# harmful operations further.)
+
+comment(#!/usr/bin/ruby -T)
+global_variable($SAFE) operator(=) integer(1)
+constant(File)operator(.)ident(open)operator(()pre_constant(ARGV)operator([)integer(0)operator(])operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+comment(# ruby warns with:)
+comment(# taint1.rb:2:in `initialize': Insecure operation - initialize (SecurityError\))
+
+global_variable($SAFE) operator(=) integer(1)
+ident(file) operator(=) pre_constant(ARGV)operator([)integer(0)operator(])
+reserved(unless) regexp<delimiter(/)content(^([)char(\\w)content(.-]+\)$)delimiter(/)>operator(.)ident(match)operator(()ident(file)operator(\))
+ ident(raise) string<delimiter(")content(filename )inline<delimiter(#{)ident(file)delimiter(})>content( has invalid characters)delimiter(")>
+reserved(end)
+ident(file) operator(=) global_variable($1)
+comment(# In ruby, even the back reference from a regular expression stays tainted.)
+comment(# you need to explicitly untaint the variable:)
+ident(file)operator(.)ident(untaint)
+constant(File)operator(.)ident(open)operator(()ident(file)operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+
+comment(# Race condition exists like in perl:)
+reserved(unless) constant(File)operator(.)ident(exists)operator(()ident(filename)operator(\)) comment(# Wrong because of race condition)
+ constant(File)operator(.)ident(open)operator(()ident(filename)operator(,) string<delimiter(")content(w)delimiter(")>operator(\))
+reserved(end)
+
+
+comment(# @@PLEAC@@_19.8)
+ident(url) operator(=) string<delimiter(")content(http://pleac.sourceforge.net/pleac_ruby/)delimiter(")>
+ident(print) string<delimiter(")content(Location: )inline<delimiter(#{)ident(url)delimiter(})>char(\\r)char(\\n)char(\\r)char(\\n)delimiter(")>
+ident(exit)
+
+comment(#!/usr/bin/ruby)
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+
+ident(cgi) operator(=) constant(CGI)operator(.)ident(new)
+ident(oreo) operator(=) constant(CGI)operator(::)constant(Cookie)operator(.)ident(new)operator(()string<delimiter(')content(name)delimiter(')> operator(=)operator(>) string<delimiter(')content(filling)delimiter(')>operator(,)
+ string<delimiter(')content(value)delimiter(')> operator(=)operator(>) string<delimiter(')content(vanilla creme)delimiter(')>operator(,)
+ string<delimiter(')content(expires)delimiter(')> operator(=)operator(>) constant(Time)operator(.)ident(now) operator(+) operator(()integer(3) operator(*) integer(30) operator(*) integer(24) operator(*) integer(60) operator(*) integer(60)operator(\))operator(,)
+ string<delimiter(')content(domain)delimiter(')> operator(=)operator(>) string<delimiter(')content(.pleac.sourceforge.net)delimiter(')>operator(\))
+
+ident(whither) operator(=) string<delimiter(')content(http://pleac.sourceforge.net/pleac_ruby/cgiprogramming.html)delimiter(')>
+
+ident(cgi)operator(.)ident(out)operator(()string<delimiter(')content(cookie)delimiter(')> operator(=)operator(>) ident(oreo)operator(,)
+ string<delimiter(')content(Location)delimiter(')> operator(=)operator(>) ident(whither)operator(\))operator({)string<delimiter(")delimiter(")>operator(})
+
+comment(#!/usr/bin/ruby)
+comment(# os_snipe - redirect to a Jargon File entry about current OS)
+ident(dir) operator(=) string<delimiter(')content(http://www.elsewhere.org/jargon/html/entry)delimiter(')>
+
+ident(agent) operator(=) constant(ENV)operator([)string<delimiter(')content(HTTP_USER_AGENT)delimiter(')>operator(])
+
+ident(page) operator(=) reserved(case)
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(Mac)delimiter(/)>operator(:) string<delimiter(')content(Macintrash.html)delimiter(')>
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(Win(dows \)?NT)delimiter(/)>operator(:) string<delimiter(')content(evil_and_rude.html)delimiter(')>
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(Win|MSIE|WebTV)delimiter(/)>operator(:) string<delimiter(')content(Microsloth_Windows.html)delimiter(')>
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(Linux)delimiter(/)>operator(:) string<delimiter(')content(Linux.html)delimiter(')>
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(HP-UX)delimiter(/)>operator(:) string<delimiter(')content(HP-SUX.html)delimiter(')>
+ reserved(when) ident(agent) operator(=)operator(~) regexp<delimiter(/)content(SunOS)delimiter(/)>operator(:) string<delimiter(')content(ScumOS.html)delimiter(')>
+ reserved(else) string<delimiter(')content(Appendix_B.html)delimiter(')>
+reserved(end)
+
+ident(print) string<delimiter(")content(Location: )inline<delimiter(#{)ident(dir)delimiter(})>content(/)inline<delimiter(#{)ident(page)delimiter(})>char(\\n)char(\\n)delimiter(")>
+
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+ident(cgi) operator(=) constant(CGI)operator(.)ident(new)
+ident(cgi)operator(.)ident(out)operator(()string<delimiter(')content(status)delimiter(')> operator(=)operator(>) string<delimiter(')content(204 No response)delimiter(')>operator(\))operator({)string<delimiter(")delimiter(")>operator(})
+comment(# this produces:)
+comment(# Status: 204 No response)
+comment(# Content-Type: text/html)
+comment(# Content-Length: 0)
+comment(# <blank line here>)
+
+
+comment(# @@PLEAC@@_19.10)
+ident(preference_value) operator(=) ident(cgi)operator(.)ident(cookies)operator([)string<delimiter(")content(preference name)delimiter(")>operator(])operator([)integer(0)operator(])
+
+ident(packed_cookie) operator(=) constant(CGI)operator(::)constant(Cookie)operator(.)ident(new)operator(()string<delimiter(")content(name)delimiter(")> operator(=)operator(>) string<delimiter(")content(preference name)delimiter(")>operator(,)
+ string<delimiter(")content(value)delimiter(")> operator(=)operator(>) string<delimiter(")content(whatever you'd like)delimiter(")>operator(,)
+ string<delimiter(")content(expires)delimiter(")> operator(=)operator(>) constant(Time)operator(.)ident(local)operator(()constant(Time)operator(.)ident(now)operator(.)ident(year) operator(+) integer(2)operator(,)
+ constant(Time)operator(.)ident(now)operator(.)ident(mon)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(day)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(hour)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(min)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(sec)operator(\)) operator(\))
+
+ident(cgi)operator(.)ident(header)operator(()string<delimiter(")content(cookie)delimiter(")> operator(=)operator(>) operator([)ident(packed_cookie)operator(])operator(\))
+
+comment(#!/usr/local/bin/ruby -w)
+comment(# ic_cookies - sample CGI script that uses a cookie)
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+
+ident(cgi) operator(=) constant(CGI)operator(.)ident(new)operator(()string<delimiter(')content(html3)delimiter(')>operator(\))
+
+ident(cookname) operator(=) string<delimiter(")content(favorite ice cream)delimiter(")>
+ident(favorite) operator(=) ident(cgi)operator(.)ident(params)operator([)string<delimiter(")content(flavor)delimiter(")>operator(])operator([)integer(0)operator(])
+ident(tasty) operator(=) ident(cgi)operator(.)ident(cookies)operator([)ident(cookname)operator(])operator([)integer(0)operator(]) operator(||) string<delimiter(')content(mint)delimiter(')>
+
+reserved(unless) ident(favorite)
+ ident(cgi)operator(.)ident(out) operator({)
+ ident(cgi)operator(.)ident(html) operator({)
+ ident(cgi)operator(.)ident(head) operator({) ident(cgi)operator(.)ident(title) operator({) string<delimiter(")content(Ice Cookies)delimiter(")> operator(}) operator(}) operator(+)
+ ident(cgi)operator(.)ident(body) operator({)
+ ident(cgi)operator(.)ident(h1) operator({) string<delimiter(")content(Hello Ice Cream)delimiter(")> operator(}) operator(+)
+ ident(cgi)operator(.)ident(hr) operator(+)
+ ident(cgi)operator(.)ident(form) operator({)
+ ident(cgi)operator(.)ident(p) operator({) string<delimiter(")content(Please select a flavor: )delimiter(")> operator(+)
+ ident(cgi)operator(.)ident(text_field)operator(()string<delimiter(")content(flavor)delimiter(")>operator(,) ident(tasty) operator(\)) operator(})
+ operator(}) operator(+)
+ ident(cgi)operator(.)ident(hr)
+ operator(})
+ operator(})
+ operator(})
+reserved(else)
+ ident(cookie) operator(=) constant(CGI)operator(::)constant(Cookie)operator(.)ident(new)operator(() string<delimiter(")content(name)delimiter(")> operator(=)operator(>) ident(cookname)operator(,)
+ string<delimiter(")content(value)delimiter(")> operator(=)operator(>) ident(favorite)operator(,)
+ string<delimiter(")content(expires)delimiter(")> operator(=)operator(>) constant(Time)operator(.)ident(local)operator(()constant(Time)operator(.)ident(now)operator(.)ident(year) operator(+) integer(2)operator(,)
+constant(Time)operator(.)ident(now)operator(.)ident(mon)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(day)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(hour)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(min)operator(,) constant(Time)operator(.)ident(now)operator(.)ident(sec)operator(\)) operator(\))
+ ident(cgi)operator(.)ident(out)operator(()string<delimiter(")content(cookie)delimiter(")> operator(=)operator(>) operator([)ident(cookie)operator(])operator(\)) operator({)
+ ident(cgi)operator(.)ident(html) operator({)
+ ident(cgi)operator(.)ident(head) operator({) ident(cgi)operator(.)ident(title) operator({) string<delimiter(")content(Ice Cookies)delimiter(")> operator(}) operator(}) operator(+)
+ ident(cgi)operator(.)ident(body) operator({)
+ ident(cgi)operator(.)ident(h1) operator({) string<delimiter(")content(Hello Ice Cream)delimiter(")> operator(}) operator(+)
+ ident(cgi)operator(.)ident(p) operator({) string<delimiter(")content(You chose as your favorite flavor `)inline<delimiter(#{)ident(favorite)delimiter(})>content('.)delimiter(")> operator(})
+ operator(})
+ operator(})
+ operator(})
+reserved(end)
+
+
+comment(# @@PLEAC@@_20.9)
+reserved(def) method(templatefile)operator(()ident(filename)operator(,) ident(fillings)operator(\))
+ ident(aFile) operator(=) constant(File)operator(.)ident(new)operator(()ident(filename)operator(,) string<delimiter(")content(r)delimiter(")>operator(\))
+ ident(text) operator(=) ident(aFile)operator(.)ident(read)operator(()operator(\))
+ ident(aFile)operator(.)ident(close)operator(()operator(\))
+ ident(pattern) operator(=) constant(Regexp)operator(.)ident(new)operator(()string<delimiter(')content(%%(.*?\)%%)delimiter(')>operator(\))
+ ident(text)operator(.)ident(gsub!)operator(()ident(pattern)operator(\)) operator({)
+ ident(fillings)operator([)global_variable($1)operator(]) operator(||) string<delimiter(")delimiter(")>
+ operator(})
+ ident(text)
+reserved(end)
+
+ident(fields) operator(=) operator({)
+ string<delimiter(')content(username)delimiter(')> operator(=)operator(>) ident(whats_his_name)operator(,)
+ string<delimiter(')content(count)delimiter(')> operator(=)operator(>) ident(login_count)operator(,)
+ string<delimiter(')content(total)delimiter(')> operator(=)operator(>) ident(minutes_used)
+operator(})
+ident(puts) ident(templatefile)operator(()string<delimiter(')content(simple.template)delimiter(')>operator(,) ident(fields)operator(\))
+
+comment(# @@INCOMPLETE@@)
+comment(# An example using databases is missing)
+
+
diff --git a/test/ruby/quotes.in.rb b/test/ruby/quotes.in.rb new file mode 100644 index 0000000..74bfe77 --- /dev/null +++ b/test/ruby/quotes.in.rb @@ -0,0 +1 @@ +print "test\n\\\\".gsub(/[\n\\]/, '\\\\\&')
diff --git a/test/ruby/quotes.out.raydebug b/test/ruby/quotes.out.raydebug new file mode 100644 index 0000000..3a55efc --- /dev/null +++ b/test/ruby/quotes.out.raydebug @@ -0,0 +1 @@ +ident(print) string<delimiter(")content(test)char(\\n)char(\\\\)char(\\\\)delimiter(")>operator(.)ident(gsub)operator(()regexp<delimiter(/)content([)char(\\n)char(\\\\)content(])delimiter(/)>operator(,) string<delimiter(')char(\\\\)char(\\\\)content(\\&)delimiter(')>operator(\))
diff --git a/test/ruby/sidebarize.in.rb b/test/ruby/sidebarize.in.rb new file mode 100644 index 0000000..6cb9e22 --- /dev/null +++ b/test/ruby/sidebarize.in.rb @@ -0,0 +1,145 @@ +#!/usr/bin/env ruby
+# Sidebarize is a quite simple converter, like a lot others.
+# But in one way Sidebarize is special: it converts
+# feeds into HTML-pages suitable for sidebars in Gecko-browsers.
+
+# import support for all kinds of feeds
+require 'rss/0.9'
+require 'rss/1.0'
+require 'rss/2.0'
+# import support for encodings
+require 'iconv'
+# import support for CGI
+require 'cgi'
+# import support for getting files from URLs
+require 'net/http'
+require 'uri'
+
+Version = '0.0.9'
+
+Header = %q(<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>%s Sidebar</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <link rel="stylesheet" type="text/css" href="sidebarize.css" />
+ </head>
+
+ <body>
+ <p>%s</p>)
+
+Footer = %q( <p>
+ <img src="fourpiece32.png" width="32" height="32" class="logo" />
+ generated by Sidebarize %s
+ </p>
+ </body>
+</html>)
+
+Entry = %q( <div>
+ <img src="arrow.png" width="6" height="11" />
+ <a href="%s">%s</a>
+ </div>)
+
+class FeedConverter
+ def initialize
+ @xml_source = ''
+ @feed_data = []
+ @feed_version = ''
+ @feed_description = ''
+ end
+
+ def from_file(filename)
+ f = File::open(filename)
+ @xml_source = f.read
+ f.close
+ end
+
+ def from_url(url)
+ @xml_source = Net::HTTP.get(URI.parse(url))
+ end
+
+ def parse
+ feed = RSS::Parser.parse(@xml_source)
+ @feed_description = feed.channel.description
+ @feed_name = feed.channel.title
+
+
+ feed.items.each do |item|
+ item_data = {}
+ item_data['title'] = item.title
+ item_data['link'] = item.link
+ @feed_data << item_data
+ end
+ end
+
+ # Output HTML from the internal data structure
+ def to_html
+ # header
+ puts Header % [convert_entity(@feed_name), convert_entity(@feed_description)]
+
+ # the entries
+ @feed_data.each do |item|
+ puts Entry % [item['link'], convert_entity(item['title'])]
+ end
+
+ # footer
+ print Footer % Version
+ end
+end
+
+# Converts entities
+# uses code by murphy extended with iconv conversion
+def convert_entity(text)
+ text = Iconv.new('iso-8859-15', 'utf-8').iconv(text)
+
+ feed = text.inspect[1...-1]
+
+ feed.gsub!(/\\([0-7]+)|(.)/m) do
+ if $2
+ $&
+ else
+ '&#%s;' % $1.to_i(8).to_s(10)
+ end
+ end
+
+ feed.gsub!('\"', '"')
+
+ return feed
+end
+
+# Starter
+def main
+ fc = FeedConverter.new
+ cgi = CGI.new
+ if cgi.has_key? 'url'
+ # yeah, the user pointed us to an URL
+ fc.from_url(cgi['url'])
+ #fc.from_file('sd.xml')
+ #fc.from_file('sbarize_design.html')
+
+ begin
+ # try to parse it and to generate HTML
+ fc.parse
+
+ puts 'Content-Type: text/html'
+ puts
+ fc.to_html
+ rescue
+ # parsing failed so show an error message
+ puts 'Content-Type: text/html'
+ puts
+ puts Header % ['No', 'The specified feed is not valid.']
+ puts Footer % Version
+ end
+ else
+ # no, we've got no URL, generate error message
+ puts 'Content-Type: text/plain'
+ puts
+ puts Header % ['No', 'You have to set the url=http://domain.tld/path/feed.xml to your feed.']
+ puts Footer % Version
+ end
+end
+
+main if __FILE__ == $0
\ No newline at end of file diff --git a/test/ruby/sidebarize.out.raydebug b/test/ruby/sidebarize.out.raydebug new file mode 100644 index 0000000..adaec34 --- /dev/null +++ b/test/ruby/sidebarize.out.raydebug @@ -0,0 +1,145 @@ +comment(#!/usr/bin/env ruby)
+comment(# Sidebarize is a quite simple converter, like a lot others.)
+comment(# But in one way Sidebarize is special: it converts)
+comment(# feeds into HTML-pages suitable for sidebars in Gecko-browsers.)
+
+comment(# import support for all kinds of feeds)
+ident(require) string<delimiter(')content(rss/0.9)delimiter(')>
+ident(require) string<delimiter(')content(rss/1.0)delimiter(')>
+ident(require) string<delimiter(')content(rss/2.0)delimiter(')>
+comment(# import support for encodings)
+ident(require) string<delimiter(')content(iconv)delimiter(')>
+comment(# import support for CGI)
+ident(require) string<delimiter(')content(cgi)delimiter(')>
+comment(# import support for getting files from URLs)
+ident(require) string<delimiter(')content(net/http)delimiter(')>
+ident(require) string<delimiter(')content(uri)delimiter(')>
+
+constant(Version) operator(=) string<delimiter(')content(0.0.9)delimiter(')>
+
+constant(Header) operator(=) string<delimiter(%q()content(<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>%s Sidebar</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <link rel="stylesheet" type="text/css" href="sidebarize.css" />
+ </head>
+
+ <body>
+ <p>%s</p>)delimiter(\))>
+
+constant(Footer) operator(=) string<delimiter(%q()content( <p>
+ <img src="fourpiece32.png" width="32" height="32" class="logo" />
+ generated by Sidebarize %s
+ </p>
+ </body>
+</html>)delimiter(\))>
+
+constant(Entry) operator(=) string<delimiter(%q()content( <div>
+ <img src="arrow.png" width="6" height="11" />
+ <a href="%s">%s</a>
+ </div>)delimiter(\))>
+
+reserved(class) class(FeedConverter)
+ reserved(def) method(initialize)
+ instance_variable(@xml_source) operator(=) string<delimiter(')delimiter(')>
+ instance_variable(@feed_data) operator(=) operator([)operator(])
+ instance_variable(@feed_version) operator(=) string<delimiter(')delimiter(')>
+ instance_variable(@feed_description) operator(=) string<delimiter(')delimiter(')>
+ reserved(end)
+
+ reserved(def) method(from_file)operator(()ident(filename)operator(\))
+ ident(f) operator(=) constant(File)operator(::)ident(open)operator(()ident(filename)operator(\))
+ instance_variable(@xml_source) operator(=) ident(f)operator(.)ident(read)
+ ident(f)operator(.)ident(close)
+ reserved(end)
+
+ reserved(def) method(from_url)operator(()ident(url)operator(\))
+ instance_variable(@xml_source) operator(=) constant(Net)operator(::)constant(HTTP)operator(.)ident(get)operator(()constant(URI)operator(.)ident(parse)operator(()ident(url)operator(\))operator(\))
+ reserved(end)
+
+ reserved(def) method(parse)
+ ident(feed) operator(=) constant(RSS)operator(::)constant(Parser)operator(.)ident(parse)operator(()instance_variable(@xml_source)operator(\))
+ instance_variable(@feed_description) operator(=) ident(feed)operator(.)ident(channel)operator(.)ident(description)
+ instance_variable(@feed_name) operator(=) ident(feed)operator(.)ident(channel)operator(.)ident(title)
+
+
+ ident(feed)operator(.)ident(items)operator(.)ident(each) reserved(do) operator(|)ident(item)operator(|)
+ ident(item_data) operator(=) operator({)operator(})
+ ident(item_data)operator([)string<delimiter(')content(title)delimiter(')>operator(]) operator(=) ident(item)operator(.)ident(title)
+ ident(item_data)operator([)string<delimiter(')content(link)delimiter(')>operator(]) operator(=) ident(item)operator(.)ident(link)
+ instance_variable(@feed_data) operator(<<) ident(item_data)
+ reserved(end)
+ reserved(end)
+
+ comment(# Output HTML from the internal data structure)
+ reserved(def) method(to_html)
+ comment(# header)
+ ident(puts) constant(Header) operator(%) operator([)ident(convert_entity)operator(()instance_variable(@feed_name)operator(\))operator(,) ident(convert_entity)operator(()instance_variable(@feed_description)operator(\))operator(])
+
+ comment(# the entries)
+ instance_variable(@feed_data)operator(.)ident(each) reserved(do) operator(|)ident(item)operator(|)
+ ident(puts) constant(Entry) operator(%) operator([)ident(item)operator([)string<delimiter(')content(link)delimiter(')>operator(])operator(,) ident(convert_entity)operator(()ident(item)operator([)string<delimiter(')content(title)delimiter(')>operator(])operator(\))operator(])
+ reserved(end)
+
+ comment(# footer)
+ ident(print) constant(Footer) operator(%) constant(Version)
+ reserved(end)
+reserved(end)
+
+comment(# Converts entities)
+comment(# uses code by murphy extended with iconv conversion)
+reserved(def) method(convert_entity)operator(()ident(text)operator(\))
+ ident(text) operator(=) constant(Iconv)operator(.)ident(new)operator(()string<delimiter(')content(iso-8859-15)delimiter(')>operator(,) string<delimiter(')content(utf-8)delimiter(')>operator(\))operator(.)ident(iconv)operator(()ident(text)operator(\))
+
+ ident(feed) operator(=) ident(text)operator(.)ident(inspect)operator([)integer(1)operator(...)operator(-)integer(1)operator(])
+
+ ident(feed)operator(.)ident(gsub!)operator(()regexp<delimiter(/)char(\\\\)content(([0-7]+\)|(.\))delimiter(/)modifier(m)>operator(\)) reserved(do)
+ reserved(if) global_variable($2)
+ global_variable($&)
+ reserved(else)
+ string<delimiter(')content(&#%s;)delimiter(')> operator(%) global_variable($1)operator(.)ident(to_i)operator(()integer(8)operator(\))operator(.)ident(to_s)operator(()integer(10)operator(\))
+ reserved(end)
+ reserved(end)
+
+ ident(feed)operator(.)ident(gsub!)operator(()string<delimiter(')content(\\")delimiter(')>operator(,) string<delimiter(')content(")delimiter(')>operator(\))
+
+ reserved(return) ident(feed)
+reserved(end)
+
+comment(# Starter)
+reserved(def) method(main)
+ ident(fc) operator(=) constant(FeedConverter)operator(.)ident(new)
+ ident(cgi) operator(=) constant(CGI)operator(.)ident(new)
+ reserved(if) ident(cgi)operator(.)ident(has_key?) string<delimiter(')content(url)delimiter(')>
+ comment(# yeah, the user pointed us to an URL)
+ ident(fc)operator(.)ident(from_url)operator(()ident(cgi)operator([)string<delimiter(')content(url)delimiter(')>operator(])operator(\))
+ comment(#fc.from_file('sd.xml'\))
+ comment(#fc.from_file('sbarize_design.html'\))
+
+ reserved(begin)
+ comment(# try to parse it and to generate HTML)
+ ident(fc)operator(.)ident(parse)
+
+ ident(puts) string<delimiter(')content(Content-Type: text/html)delimiter(')>
+ ident(puts)
+ ident(fc)operator(.)ident(to_html)
+ reserved(rescue)
+ comment(# parsing failed so show an error message)
+ ident(puts) string<delimiter(')content(Content-Type: text/html)delimiter(')>
+ ident(puts)
+ ident(puts) constant(Header) operator(%) operator([)string<delimiter(')content(No)delimiter(')>operator(,) string<delimiter(')content(The specified feed is not valid.)delimiter(')>operator(])
+ ident(puts) constant(Footer) operator(%) constant(Version)
+ reserved(end)
+ reserved(else)
+ comment(# no, we've got no URL, generate error message)
+ ident(puts) string<delimiter(')content(Content-Type: text/plain)delimiter(')>
+ ident(puts)
+ ident(puts) constant(Header) operator(%) operator([)string<delimiter(')content(No)delimiter(')>operator(,) string<delimiter(')content(You have to set the url=http://domain.tld/path/feed.xml to your feed.)delimiter(')>operator(])
+ ident(puts) constant(Footer) operator(%) constant(Version)
+ reserved(end)
+reserved(end)
+
+ident(main) reserved(if) pre_constant(__FILE__) operator(==) global_variable($0)
\ No newline at end of file diff --git a/test/ruby/simple.in.rb b/test/ruby/simple.in.rb new file mode 100644 index 0000000..3f5e390 --- /dev/null +++ b/test/ruby/simple.in.rb @@ -0,0 +1,2 @@ +puts "Hello, World!"
+p 2 * 19
diff --git a/test/ruby/simple.out.raydebug b/test/ruby/simple.out.raydebug new file mode 100644 index 0000000..7c11552 --- /dev/null +++ b/test/ruby/simple.out.raydebug @@ -0,0 +1,2 @@ +ident(puts) string<delimiter(")content(Hello, World!)delimiter(")>
+ident(p) integer(2) operator(*) integer(19)
diff --git a/test/ruby/suite.rb b/test/ruby/suite.rb new file mode 100644 index 0000000..b69cf6a --- /dev/null +++ b/test/ruby/suite.rb @@ -0,0 +1,9 @@ +class RubyTest < CodeRaySuite
+
+ @file = __FILE__
+ LANG = :ruby
+ EXTENSION = 'rb'
+
+end
+
+$suite << RubyTest.suite if $suite
diff --git a/test/ruby/undef.in.rb b/test/ruby/undef.in.rb new file mode 100644 index 0000000..795483d --- /dev/null +++ b/test/ruby/undef.in.rb @@ -0,0 +1,18 @@ +undef /
+undef ,
+undef --
+
+undef
+# bla
+[]=
+
+undef undef
+undef /,/,:/
+
+undef &,&&
+
+:simple
+:"bla"
+:"#{undef :blubb}#@@cv"
+
+undef :"bla", /, :"#{undef :blubb}#@@cv"
diff --git a/test/ruby/undef.out.raydebug b/test/ruby/undef.out.raydebug new file mode 100644 index 0000000..4c19712 --- /dev/null +++ b/test/ruby/undef.out.raydebug @@ -0,0 +1,18 @@ +reserved(undef) method(/)
+reserved(undef) operator(,)
+reserved(undef) method(-)operator(-)
+
+reserved(undef)
+comment(# bla)
+method([]=)
+
+reserved(undef) method(undef)
+reserved(undef) method(/)operator(,)method(/)operator(,)symbol(:/)
+
+reserved(undef) method(&)operator(,)method(&)operator(&)
+
+symbol(:simple)
+symbol<symbol(:)delimiter(")content(bla)delimiter(")>
+symbol<symbol(:)delimiter(")inline<delimiter(#{)reserved(undef) symbol(:blubb)delimiter(})>escape(#)class_variable(@@cv)delimiter(")>
+
+reserved(undef) symbol<symbol(:)delimiter(")content(bla)delimiter(")>operator(,) method(/)operator(,) symbol<symbol(:)delimiter(")inline<delimiter(#{)reserved(undef) symbol(:blubb)delimiter(})>escape(#)class_variable(@@cv)delimiter(")>
diff --git a/test/ruby/zero.in.rb b/test/ruby/zero.in.rb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/ruby/zero.in.rb diff --git a/test/ruby/zero.out.raydebug b/test/ruby/zero.out.raydebug new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/ruby/zero.out.raydebug diff --git a/test/suite.rb b/test/suite.rb new file mode 100644 index 0000000..dca72ef --- /dev/null +++ b/test/suite.rb @@ -0,0 +1,106 @@ +mydir = File.dirname(__FILE__)
+$:.unshift mydir + '/../lib/'
+
+$VERBOSE = true
+
+require 'coderay'
+CodeRay::Encoders[:tokens]
+CodeRay::Encoders[:html]
+
+require 'test/unit'
+include Test::Unit
+
+class CodeRaySuite < TestCase
+
+ def self.dir &block
+ @dir ||= File.dirname(@file)
+ if block
+ Dir.chdir @dir, &block
+ end
+ @dir
+ end
+
+ def dir &block
+ self.class.dir(&block)
+ end
+
+ def extension
+ 'in.' + self.class::EXTENSION
+ end
+
+ def lang
+ self.class::LANG
+ end
+
+ def test_ALL
+ CodeRay::Scanners.load lang
+ tokenizer = CodeRay::Encoders[:debug].new
+ highlighter = CodeRay::Encoders[:html].new(
+ :tab_width => 2,
+ :line_numbers => :table,
+ :wrap => :page,
+ :hint => :info
+ )
+
+ dir do
+ for input in Dir["*.#{extension}"]
+ puts "[ testing #{input}... ]"
+ name = File.basename(input, ".#{extension}")
+ output = name + '.out.' + tokenizer.file_extension
+ code = File.open(input, 'rb') { |f| break f.read }
+
+ tokens = CodeRay.scan code, lang
+ result = tokenizer.encode_tokens tokens
+ highlighted = highlighter.encode_tokens tokens
+
+ File.open(name + '.html', 'w') do |f| f.write highlighted end
+
+ if File.exist? output
+ expected = File.read output
+ ok = expected == result
+ computed = output.sub('.out.', '.computed.')
+ unless ok
+ File.open(computed, 'w') { |f| f.write result }
+ print `gvimdiff #{output} #{computed}` if $DEBUG
+ end
+ assert(ok, "Scan error: #{computed} != #{output}")
+ else
+ File.open(output, 'w') do |f| f.write result end
+ puts "New test: #{output}"
+ end
+
+ end
+ end
+ end
+
+end
+
+require 'test/unit/testsuite'
+$suite = TestSuite.new
+
+def load_suite name
+ begin
+ require name + '/suite.rb'
+ rescue LoadError
+ $stderr.puts <<-ERR
+
+!! Folder #{File.split(__FILE__).first + '/' + name} not found
+
+ ERR
+ false
+ end
+end
+
+if subsuite = ARGV.find { |a| break $1 if a[/^([^-].*)/] }
+ load_suite(subsuite) or exit
+else
+ Dir[mydir + '/*/'].each { |suite| load_suite suite }
+end
+
+if ARGV.include? '-f'
+ require 'test/unit/ui/fox/testrunner'
+ UI::Fox::TestRunner.run $suite
+else
+ require 'test/unit/ui/console/testrunner'
+ UI::Console::TestRunner.run $suite
+end
|