Download Thinking in Ruby - Leuphana Universität Lüneburg

Document related concepts
no text concepts found
Transcript
H
AC
CO
RUBY COACH
— Scripting in Ruby —
RU
BY
Hinrich E. G. Bonin1
1
Prof. Dr. rer. publ. Dipl.-Ing. Dipl.-Wirtsch.-Ing. Hinrich E. G. Bonin lehrt
Informatik an der Leuphana Universität Lüneburg, Email: [email protected], Adresse: An der Eulenburg 6, D-21391 Reppenstedt, Germany.
H
2
Abstract
AC
“Ruby is the interpreted scripting language for quick and easy object-oriented
programming. It has many features to
process text files and to do system management tasks (as in Perl). It is simple,
straight-forward, and extensible.” (→ file readme.txt)
BY
CO
‘, ‘,
() ()
() ()
+--------+
( o o )
| Ruby
|
ˆˆ ( @__)___| is
|
||
(
)
| fun!
|
++==(
)\ +--------+
(
)\\
(
) vv
(
)
__//˜˜\\__
(___) (___)
RU
Remark: This is a draft document and continues
to be revised. The latest version can be found at
http://as.uni-lueneburg.de/publikation/rubyall.pdf.
Please send comments to:
mailto:[email protected]
H
AC
Inhaltsverzeichnis
Preface
2
Examples and Exercises
2.1 Cult Programm HelloWorld . .
2.2 Factorial Function fac . . . . . .
2.3 Prime Numbers prime . . . . . .
2.4 Input and Output . . . . . . . . .
2.5 Transaction . . . . . . . . . . . .
2.6 Downloading Web Pages . . . . .
2.7 Several Processes . . . . . . . . .
2.8 Directory Access . . . . . . . . .
2.9 Inheritance . . . . . . . . . . . .
2.10 Singleton Method . . . . . . . . .
2.11 Word Couter . . . . . . . . . . . .
2.12 Shallow Copy . . . . . . . . . . .
2.13 Namespace — module . . . . .
2.14 Mixins — include . . . . . . .
2.15 Serialization — Marshaling . . . .
2.16 Reflection . . . . . . . . . . . . .
2.17 Recursion . . . . . . . . . . . . .
2.18 Simple Continuation . . . . . . .
2.19 Calling Future Code . . . . . . . .
2.20 CGI (Common Gateway Interface)
2.21 Quadric . . . . . . . . . . . . . .
2.22 Biorhythm . . . . . . . . . . . . .
2.23 WIN32OLE — Internetexplorer .
2.24 WIN32OLE — Excel . . . . . . .
RU
BY
CO
1
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
10
11
12
13
15
16
17
18
19
20
22
24
25
27
29
31
34
35
37
38
42
46
48
Software Engineering Tools
3.1 ri — Ruby Information at your fingertips
3.2 irb — Interactive Ruby Shell . . . . . .
3.3 ruby-mode — Emacs Mode . . . . . .
3.4 rd-mode — Emacs Mode . . . . . . . .
3.5 eruby — Embedding Ruby in HTML . .
3.6 Framework Ruby on Rails . . . . . . . .
3.7 Eclipse — Plug-In . . . . . . . . . . . . .
3.8 rd2 — formater tool . . . . . . . . . . .
3.8.1 Prerequisite racc tool . . . . . .
3.8.2 rdtool — Installation . . . . .
3.9 DyBASE — Object Oriented DBMS . . .
3.9.1 Application Program Interface . .
3.9.2 Example TestLink.rb . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
51
51
52
53
54
55
56
56
57
60
60
63
65
71
.
.
.
.
.
.
.
.
77
77
77
77
77
77
78
79
83
CO
AC
3
H
INHALTSVERZEICHNIS
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
RU
BY
A Resources
A.1 Web Sites . . . . . . . . . .
A.1.1 Ruby . . . . . . . .
A.1.2 Java . . . . . . . . .
A.1.3 Updates to this Book
A.2 Glossary . . . . . . . . . . .
A.3 Bibliography . . . . . . . .
A.4 About this Document . . . .
A.5 Index . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
H
CO
Preface
AC
Kapitel 1
, ,
() ()
() ()
+------+
( . o )
| Easy-|
( @__)_____| to- |
(
)
| use! |
//(
)\\
+------+
//(
)\\
vv (
) vv
(
)
__//˜˜\\__
(___) (___)
• Simple Syntax
• “Normal” Object-Oriented features (ex. class, method calls)
• “Advanced”
Object-Oriented
features (ex. Mix-in, Singletonmethod)
RU
BY
• Operator Overloading
• Exception Handling
• Iterators and Closures
• Garbage Collection
• Dynamic Loading of Object files(on some architecture)
• Highly Portable(works on many
UNIX machines, and on DOS,
Windows, Mac, BeOS etc.)
A modern object oriented programming language is JavaT M 1 . First
let’s compare Ruby with Java:
1
More for example → section A.1.2 p. 77 or → [Arnold / Gosling, 1996].
5
KAPITEL 1. PREFACE
CO
AC
H
6
Legende:
Script RubyCoach.rb →p. 6.
Produced with the following command:
d:\bonin\rubyScript\code>RubyCoach
> ../html/RubyCoach.xml
RubyCoach.xml loaded into Microsoft Windows XP [Version
5.1.2600].
BY
Abbildung 1.1: Contents of this book Ruby Coach
• Ruby’s variable and expressions are not statically typed.
• All data (including Integer, String etc.) in Ruby are class
instances.
• Ruby’s module can be used to share implementation among classes.
RU
• Ruby is an interpreted language.
Ruby program files use the suffix “*.rb”. If you don’t want a console
window to be created, use the suffix “*.rbw” instead. Program files may
be created using any plain text editor such as Emacs or Eclipse.
Script RubyCoach.rb
H
7
CO
AC
#
# Contents of Ruby Coach
#
# Hinrich Bonin
# 4-Dec-2003 19-Jul-2007
#
class RubyCoach
def initialize()
@chapter = ["Preface",
"Exercises",
"Software Engineering Tools",
"Resources", "Index"
]
end
def contents
puts "<?xml version=\"1.0\" " +
"encoding=\"utf-8\" ?>"
puts "<book>"
puts "<title>Ruby Coach</title>"
@chapter.each {
|i| puts "<chapter>#{i}</chapter>"
}
puts "</book>"
end
BY
end
RubyCoach.new.contents
# EOF 193.174.33.66 D:/bonin/rubyScript/code/RubyCoach.rb
Notation Conventions
RU
The RUBY COACH uses a typewriter-like font to show source code
examples.
class Foo
def methodA(n)
.
.
.
KAPITEL 1. PREFACE
H
8
end
AC
.
.
.
bar = Foo.new
.
.
.
end
RU
BY
CO
Within the text, Foo#methodA() is a reference to the instance method
methodA() of the class Foo. The notation Foo.new or Foo::new
is a class method. The notation Foo::EOF is a class constant.
The RUBY COACH contains snippets of code. The result is shown
after the sign ==>.
H
AC
Kapitel 2
Examples and Exercises
CO
For an instant I thought Ruby was reading my mind . . .
if matz can do that, it IS a powerful language!
Hat Fulton
(→[Röhrl+, 2002] p. 3)
2.1 Cult Programm HelloWorld
Command line Hello World!
BY
D:\bonin\rubyScript>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript>ruby -e ’puts "Hello World!"’
Hello World!
D:\bonin\rubyScript>
Script HelloWorld.rb
RU
#
# Simple class example
#
# Hinrich Bonin
# 3-Dec-2003
#
class HelloWorld
9
H
KAPITEL 2. EXAMPLES AND EXERCISES
10
end
o = HelloWorld.new
puts o.msg
print "Please press Enter-Key."
$stdin.gets
CO
Protocol HelloWorld.log
AC
attr_reader :msg
def initialize
@msg = "Hello World!"
end
d:\bonin\rubyScript>ruby --copyright
ruby - Copyright (C) 1993-2003 Yukihiro Matsumoto
d:\bonin\rubyScript>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
d:\bonin\rubyScript>ruby ./code/HelloWorld.rb
BY
Hello World!
Please press Enter-Key.
d:\bonin\rubyScript>
2.2 Factorial Function fac
Script fac.rb
RU
#
# Factorial function
#
# Hinrich Bonin
# 4-Dec-2003
#
def fac(n)
result = 1
(2..n).each {|i| result *= i}
result
end
#
2.3. PRIME NUMBERS PRIME
CO
AC
H
11
Legende: Ruby Script HelloWorld.rb in Microsoft Windows XP
[Version 5.1.2600].
Abbildung 2.1: Running HelloWorld.rb
puts fac(20)
#
# EOF 193.174.33.66 D:/bonin/rubyScript/code/fac.rb
BY
Protocol fac.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>fac
2432902008176640000
RU
D:\bonin\rubyScript\code>ruby -e ’require \’fac\’’
2432902008176640000
D:\bonin\rubyScript\code>
2.3 Prime Numbers prime
Script prime.rb This example uses print. If the output field se-
print
KAPITEL 2. EXAMPLES AND EXERCISES
H
12
AC
parator “$,” is not nil, its contents will appear between each field.
If the output record separator “$\” is not nil, it will be appended to
the output. Objects that aren’t strings will be converted by calling their
to s method.
Protocol prime.log
CO
#
# Prime Numbers
#
# Hinrich Bonin
# 10-Dec-2003
#
a = Array.new
for i in 2..17 do
a[i] = i unless (2..i-1).find{|j| i % j == 0}
end
$, = ", "
$\ = "\n"
print a
#
# EOF 193.174.33.66 D:/bonin/rubyScript/code/prime.rb
BY
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>prime
, , 2, 3, , 5, , 7, , , , 11, , 13, , , , 17
D:\bonin\rubyScript\code>
2.4 Input and Output
RU
Script inout.rb
#
# Input & Output
#
# Hinrich Bonin
# 10-Dec-2003
#
2.5. TRANSACTION
H
13
Text file myHounds.txt
CO
Elsa vom Erlenbruch
Wulf von Wallesau
Xander von Thurewang
Xara vom Bremberg
AC
File.open("myHounds.txt", "r") {|aFile|
aFile.each_line {|line|
print line if line =˜ /von/
}
}
File.open("myHounds.txt", "w") {|aFile|
aFile.print "Klara von Wolfsburg\n"
}
# EOF 193.174.33.66 D:/bonin/rubyScript/code/inout.rb
Protocol inout.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
BY
D:\bonin\rubyScript\code>inout
Wulf von Wallesau
Xander von Thurewang
D:\bonin\rubyScript\code>inout
Klara von Wolfsburg
D:\bonin\rubyScript\code>
2.5 Transaction
RU
A code block is just chunk of code between {. . .} or do. . .end. You
can associate it with a call to a method. That method can then invoke
the block one or more times using the Ruby yield statement. First we
show this in action with a simple example running in irb (Interactive
Ruby Shell → section 3.2 p. 52).
D:\bonin\rubyScript>irb
irb(main):001:0> def callBlock
yield
KAPITEL 2. EXAMPLES AND EXERCISES
H
14
AC
irb(main):002:1> yield
irb(main):003:1> yield
irb(main):004:1> end
=> nil
irb(main):005:0> callBlock {puts "Now I know yield."}
Now I know yield.
Now I know yield.
=> nil
irb(main):006:0> quit
D:\bonin\rubyScript>
CO
Script transaction.rb
BY
##
# Making the file responsible
# for closing itself.
# (Block for transaction)
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
class File
def File.openProcessClose(*args)
f = File.open(*args)
yield f
f.close()
end
end
File.openProcessClose("myHounds.txt", "r") do |aFile|
print while aFile.gets
end
RU
# EOF 193.174.33.66 D:/bonin/rubyScript/code/transaction.rb
Text file myHounds.txt → p. 13
Protocol transaction.log
2.6. DOWNLOADING WEB PAGES
H
15
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
AC
D:\bonin\rubyScript\code>transaction
Elsa vom Erlenbruch
Wulf von Wallesau
Xander von Thurewang
Xara vom Bremberg
D:\bonin\rubyScript\code>
2.6 Downloading Web Pages
Downloading three
Web pages in parallel:
http://as.fhnon.de/index.php3
http://nemo.fhnon.de/index.html
http://webrat.fhnon.de/index.jsp
Hinrich Bonin
11-Dec-2003
BY
#
#
#
#
#
#
#
#
#
#
CO
Script webpages.rb
require ’net/http’
RU
urls = %w(as.fhnon.de nemo.fhnon.de webrat.fhnon.de)
threads = []
for url in urls
threads << Thread.new(url) {|myP|
h = Net::HTTP.new(myP, 80)
puts "Loading: #{myP}"
resp, data = h.get(’/’, nil )
puts "Response for #{myP}/: #{resp.message}"
resp, data = h.get(’/index.jsp’, nil )
puts "Response for #{myP}/index.jsp: #{resp.message}"
}
end
threads.each {|aTh| aTh.join}
# EOF 193.174.33.66 D:/bonin/rubyScript/code/webpages.rb
KAPITEL 2. EXAMPLES AND EXERCISES
H
16
AC
Protocol webpages.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>
2.7 Several Processes
CO
D:\bonin\rubyScript\code>webpages
Loading: as.fhnon.de
Loading: nemo.fhnon.de
Loading: webrat.fhnon.de
Response for nemo.fhnon.de/: OK
Response for webrat.fhnon.de/: Moved Temporarily
Response for nemo.fhnon.de/index.jsp: Not Found
Response for webrat.fhnon.de/index.jsp: OK
Response for as.fhnon.de/: OK
Response for as.fhnon.de/index.jsp: Not Found
system()
BY
Protocol processes.log
Remark: Interactive Ruby Shell irb → section 3.2 p. 52.
One problem with Kernel.system() (short system()) is that
the command’s output will simply go to the same destination as your
program’s output.
D:\bonin\rubyScript\code>irb --version
irb 0.9(02/07/03)
RU
D:\bonin\rubyScript\code>irb
irb(main):001:0> result =
irb(main):002:0* system("type wordCounter.rb > outfile.txt")
=> true
irb(main):003:0> result
=> true
irb(main):004:0> system("type outfile.txt")
#
# Counts the words in the text
2.8. DIRECTORY ACCESS
H
17
AC
# "matz.txt"
# Hinrich Bonin
.
.
.
irb(main):005:0> ruby --version
NameError: undefined local variable or
method ‘version’ for main:Object
from (irb):5
irb(main):006:0> ‘ruby --version‘
=> "ruby 1.8.0 (2003-08-04) [i386-mswin32]\n"
irb(main):007:0> exit
CO
D:\bonin\rubyScript\code>
2.8 Directory Access
Script dir.rb
Remark: Source code → /ruby/Ruby-1.8.0/samples/dir.rb
BY
# directory access
# list all files but .*/*˜/*.o
dirp = Dir.open(".")
for f in dirp
case f
when /ˆ\./, /˜$/, /\.o/
# do not print
else
print f, "\n"
end
end
dirp.close
RU
Protocol dir.log
D:\bonin\rubyScript>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript>ruby ./code/dir.rb
body.tmp
code
KAPITEL 2. EXAMPLES AND EXERCISES
H
18
D:\bonin\rubyScript>
2.9 Inheritance
BY
Script Hound.rb
CO
AC
emlines2.sty
eps
head.tmp
log
material
rubyall.aux
rubyall.dvi
rubyall.idx
rubyall.ilg
rubyall.ind
rubyall.lof
rubyall.lot
rubyall.pdf
rubyall.ps
rubyall.tex
rubyall.toc
run.bat
stempel.pro
verbfile.sty
RU
#
# Simple inheritance example
#
# Hinrich Bonin
# 3-Dec-2003
#
class Mammal
def initialize(name,sex)
@name = name
@sex = sex
end
def to_s
"#{@name} (#{@sex})"
end
end
class Hound < Mammal
2.10. SINGLETON METHOD
H
19
AC
def initialize(name,sex,performance,race)
super(name,sex)
@performance = performance
@race = race
end
def to_s
"Hound: " +
"#{@race} " +
super +
" --- #{@performance}"
end
end
CO
elsa = Hound.new("Elsa vom Erlenbruch", "male" ,
"SWI", "German Setter")
puts(elsa.to_s)
# EOF 193.174.33.66 D:/bonin/rubyScript/code/Hound.rb
Protocol Hound.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
BY
D:\bonin\rubyScript\code>Hound
Hound: German Setter Elsa vom Erlenbruch (male) --- SWI
D:\bonin\rubyScript\code>
2.10 Singleton Method
Script Foo.rb
Remark: Source code idea → [Röhrl+, 2002] p. 8
RU
#
# Singleton Method
#
# Hinrich Bonin
# 7-Dec-2003
#
class Foo
def method_missing(methId)
print "The method ", methId.id2name,
H
KAPITEL 2. EXAMPLES AND EXERCISES
20
# Method specified for f instance of FOO
def f.saySomething
print "I like Ruby! \n"
end
f.saySomething
# Not specified for other Foo objects
Foo.new.saySomething
AC
" is not specified.\n"
end
end
f = Foo.new
f.saySomething
CO
# EOF 193.174.33.66 D:/bonin/rubyScript/code/Foo.rb
Protocol Foo.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>Foo
The method saySomething is not specified.
I like Ruby!
The method saySomething is not specified.
BY
D:\bonin\rubyScript\code>
2.11 Word Couter
Script wordCounter.rb
Remark: Source code idea → [Röhrl+, 2002] p. 7
RU
#
# Counts the words in the text
# "matz.txt"
# Hinrich Bonin
# 7-Dec-2003
#
freq = Hash.new(0)
open("matz.txt").read.scan(/\w+/){ |word|
freq[word] +=1
}
freq.sort.each { |word, number|
2.11. WORD COUTER
puts "#{number} : #{word}"
}
H
21
Text file matz.txt
AC
# EOF 193.174.33.66 D:/bonin/rubyScript/code/wordCounter.rb
Man is driven to create;
I know I really love to create things.
And while I’m not good at painting,
drawing, or music, I can write software.
CO
It is my hope that both Ruby
and this book will serve to make
your programming easy and enjoyable.
Have fun!
Yukihiro Matsumoto, a.k.a. ‘‘Matz’’
Japan, October 2000
Protocol wordCounter.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
BY
D:\bonin\rubyScript\code>wordCounter
1 : 2000
1 : And
1 : Have
4 : I
1 : It
1 : Japan
1 : Man
1 : Matsumoto
1 : Matz
1 : October
1 : Ruby
1 : Yukihiro
2 : a
2 : and
1 : at
1 : book
1 : both
1 : can
2 : create
KAPITEL 2. EXAMPLES AND EXERCISES
AC
drawing
driven
easy
enjoyable
fun
good
hope
is
k
know
love
m
make
music
my
not
or
painting
programming
really
serve
software
that
things
this
to
while
will
write
your
CO
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
BY
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
3
1
1
1
1
H
22
D:\bonin\rubyScript\code>
2.12 Shallow Copy
Object#clone produces a shallow copy of an object of the class
Object. The instance variables of object are copied, but not the objects they reference.
RU
clone
Script shallowcopy.rb
##
# Cloning an object
#
2.12. SHALLOW COPY
class Foo
attr_accessor :slot
end
AC
# @author Hinrich Bonin
# @version 1.0
# 20-Dec-2003
#
H
23
myoriginal = Foo.new
myoriginal.slot = "Elsa"
puts myoriginal.inspect
myclone = myoriginal.clone
puts myclone.inspect
CO
myoriginal.slot[0,4] = "xxxx"
puts myoriginal.inspect
puts myclone.inspect
myclone = myoriginal.clone
# Cloning the slot reference
myclone.slot = myoriginal.slot.clone
myoriginal.slot[0,4] = "Emma"
puts myoriginal.inspect
puts myclone.inspect
BY
# EOF 193.174.33.66 D:/bonin/rubyScript/code/shallowcopy.rb
Protocol shallowcopy.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
D:\bonin\rubyScript\code>shallowcopy
#<Foo:0x2897678 @slot="Elsa">
#<Foo:0x2897588 @slot="Elsa">
#<Foo:0x2897678 @slot="xxxx">
#<Foo:0x2897588 @slot="xxxx">
#<Foo:0x2897678 @slot="Emma">
#<Foo:0x28974c8 @slot="xxxx">
D:\bonin\rubyScript\code>
H
KAPITEL 2. EXAMPLES AND EXERCISES
24
2.13 Namespace — module
Script Foo.rb
CO
##
# Simple namespace example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
module Foo
V = 1
def Foo.f(n)
print "Doing Foo::f(#{n})\n"
n + V
end
AC
The module mechanism provide a namespace and prevent name clashes.
Remark: Module constants are named just like class constants, with an
initial uppercase letter.
def Foo.g(n)
print "Doing Foo::g(#{n})\n"
n * V
end
BY
end
# EOF 193.174.33.66
# D:/bonin/rubyScript/code/de/fhnon/as/Foo.rb
Script Bar.rb
RU
##
# Simple namespace example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
module Bar
V = 2
def Bar.f(n)
print "Doing Bar::f(#{n})\n"
n - V
end
2.14. MIXINS — INCLUDE
end
H
AC
def Bar.g(n)
print "Doing Bar::g(#{n})\n"
n / V
end
25
# EOF 193.174.33.66
# D:/bonin/rubyScript/code/de/fhnon/as/Bar.rb
Script main.rb
CO
##
# Simple namespace example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
require "de/fhnon/as/Foo"
require "de/fhnon/as/Bar"
puts Foo.f(Bar.f(Foo.g(Bar.g(Bar::V))))
# EOF 193.174.33.66 D:/bonin/rubyScript/code/main.rb
Protocol main.log
BY
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>main
Doing Bar::g(2)
Doing Foo::g(1)
Doing Bar::f(1)
Doing Foo::f(-1)
0
RU
D:\bonin\rubyScript\code>
2.14 Mixins — include
The Ruby include statement makes a reference to a named module. If
multiple classes include that module, they’ll all point to the same thing.
If you change the definition of a method within a module, all classes that
include that module will exhibit the new behavior.
include
H
KAPITEL 2. EXAMPLES AND EXERCISES
26
Script Inside.rb
AC
##
# Simple mixins example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
module Inside
def show(n)
"#{n}: #{self.inspect}"
end
end
Script Innerpart.rb
CO
# EOF 193.174.33.66
# D:/bonin/rubyScript/code/de/fhnon/as/Inside.rb
BY
##
# Simple mixins example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
module Innerpart
def show(n)
"#{n}: Here is method Innerpart\#show(#{n})!"
end
end
# EOF 193.174.33.66
# D:/bonin/rubyScript/code/de/fhnon/as/Innerpart.rb
Script mixins.rb
RU
##
# Simple mixins example
#
# @author Hinrich Bonin
# @version 1.0
# 21-Dec-2003
#
require "de/fhnon/as/Inside"
require "de/fhnon/as/Innerpart"
class Foo
o = Foo.new
r = Bar.new
z = Baz.new
CO
class Baz
include Inside
attr_accessor :x
end
AC
include Innerpart
include Inside
attr_accessor :x
end
class Bar
include Inside
include Innerpart
attr_accessor :x
end
27
H
2.15. SERIALIZATION — MARSHALING
o.x = "Foo value"
r.x = "Bar value"
z.x = "Baz value"
puts o.show(0)
puts r.show(1)
puts z.show(2)
BY
# EOF 193.174.33.66 D:/bonin/rubyScript/code/mixins.rb
Protocol mixins.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript\code>mixins
0: #<Foo:0x2896400 @x="Foo value">
1: Here is method Innerpart#show(1)!
2: #<Baz:0x2896340 @x="Baz value">
RU
D:\bonin\rubyScript\code>
2.15 Serialization — Marshaling
Ruby calls this kind of serialization marshaling. Saving an object and
some or all of its components is done using the method Marshal::dump.
H
KAPITEL 2. EXAMPLES AND EXERCISES
28
Script serial.rb
#
# Serialization of Objects
# = Marshaling
# Hinrich Bonin
# 8-Dec-2003
#
thing, thingBackup = Object.new
CO
point = Struct.new(’Point’, :x, :y)
x = point.new(1,1)
y = point.new(7,7)
AC
Typically, you will dump an entire object tree starting with some given
object. Later on, you can reconstitute the object using Marshal::load.
rectangle = Struct.new(’Rectangle’, :origin, :corner);
r = rectangle.new(x, y)
thing = [r, x, y]
File.open("serialThing", "w+") do |f|
Marshal.dump(thing, f)
end
BY
File.open("serialThing") do |f|
thingBackup = Marshal.load(f)
end
print "Point y backup: ", thingBackup[2], "\n"
# EOF 193.174.33.66 D:/bonin/rubyScript/code/serial.rb
Protocol serial.log
RU
d:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
d:\bonin\rubyScript\code>serial
Point y backup: #<struct Struct::Point x=7, y=7>
D:\bonin\rubyScript\code>dir serialThing
84 serialThing
D:\bonin\rubyScript\code>
2.16. REFLECTION
H
29
2.16 Reflection
Script reflection.rb
AC
#
# Object Space and Reflection
# Hinrich Bonin
# 8-Dec-2003
#
point = Struct.new(’Point’, :a, :b)
x = point.new(1,1)
y = point.new(7,7)
CO
print "*** Struct object applies to ",
x.methods.length, " methods: ***\n"
x.methods.sort.each {|m| print m, "\n" }
print "*** Object Space: ***\n"
ObjectSpace.each_object(Struct) {
|o| print o, "\n" }
# EOF 193.174.33.66 D:/bonin/rubyScript/code/reflection.rb
Protocol reflection.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
BY
D:\bonin\rubyScript\code>reflection
*** Struct object applies to 74 methods: ***
==
===
=˜
[]
[]=
__id__
__send__
a
a=
all?
any?
b
b=
class
clone
collect
detect
RU
AC
BY
display
dup
each
each_pair
each_with_index
entries
eql?
equal?
extend
find
find_all
freeze
frozen?
grep
hash
id
include?
inject
inspect
instance_eval
instance_of?
instance_variable_get
instance_variable_set
instance_variables
is_a?
kind_of?
length
map
max
member?
members
method
methods
min
nil?
object_id
partition
private_methods
protected_methods
public_methods
reject
respond_to?
select
send
singleton_methods
H
KAPITEL 2. EXAMPLES AND EXERCISES
CO
30
2.17. RECURSION
H
31
CO
AC
size
sort
sort_by
taint
tainted?
to_a
to_s
type
untaint
values
values_at
zip
*** Object Space: ***
#<struct Struct::Point a=7, b=7>
#<struct Struct::Point a=1, b=1>
D:\bonin\rubyScript\code>
2.17 Recursion
Script turnround.rb
Remark: Equivalent source code in LISP language Scheme →[Bonin, 1991]
p. 97 ff.
BY
##
# Inverting an Array object
#
# Recursive functions
# turnround(a)
# invert(a)
#
# @author Hinrich Bonin
# @version 1.0
# 20-Dec-2003
#
myarray = ["a", "b", "c", "d"]
RU
def firstElement(a)
return a.first
end
def restArray(a)
b = a.clone
b.shift
return b
KAPITEL 2. EXAMPLES AND EXERCISES
end
CO
print "Turn round an object of type: " +
myarray.class.to_s + "\n"
print "Using append construction" + "\n"
print "
Start myarray ==> " +
myarray.to_s + "\n"
print "turnround(myarray) ==> " +
turnround(myarray).to_s + "\n"
print "
End myarray ==> " +
myarray.to_s + "\n"
AC
def turnround(a)
if a.empty?
return a
else
return turnround(
restArray(a)).concat([firstElement(a)])
end
end
H
32
print "\nInverting with more recursivity \n"
# Step one: invert the rest array
print "Step one
==> " +
turnround(
restArray(myarray)).to_s + "\n"
BY
# Step two: delete the first element from step one
print "Step two
==> " +
restArray(
turnround(
restArray(myarray))).to_s + "\n"
# Step three: invert the result of step two
print "Step three ==> " +
turnround(
restArray(
turnround(
restArray(myarray)))).to_s + "\n"
RU
# Step four: add first element (= "a") in result of step three
print "Step four ==> " +
[ firstElement(myarray) ].concat(
turnround(restArray(turnround(restArray(myarray))))
).to_s + "\n"
# Step five: invert result of step four
print "Step five ==> " +
turnround(
2.17. RECURSION
H
33
AC
[firstElement(myarray)].concat(
turnround(
restArray(
turnround(
restArray(myarray))))
)).to_s + "\n"
# Step six: last element
print "Step six
==> " +
[firstElement(
turnround(
restArray(myarray)))].to_s + "\n"
CO
# Step seven: <last element>.concat(turnround(
#
<array without last element = step four>))
print "Step seven ==> " +
[firstElement(
turnround(
restArray(myarray)))].
concat(
turnround(
[firstElement(myarray)].concat(
turnround(
restArray(
turnround(
restArray(myarray))))
))).to_s + "\n"
RU
BY
def invert(a)
if a.empty?
return a
else
if [restArray(a)].empty?
return a
else
return [firstElement(
invert(restArray(a)))].concat(
invert([firstElement(a)].concat(
invert(restArray(
invert(restArray(a)))))))
end
end
end
print invert(myarray).to_s
# EOF 193.174.33.66 D:/bonin/rubyScript/code/turnround.rb
KAPITEL 2. EXAMPLES AND EXERCISES
Protocol turnround.log
D:\bonin\rubyScript\code>turnround
Turn round an object of type: Array
Using append construction
Start myarray ==> abcd
turnround(myarray) ==> dcba
End myarray ==> abcd
AC
d:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
H
34
BY
D:\bonin\rubyScript\code>
CO
Inverting with more recursivity
Step one
==> dcb
Step two
==> cb
Step three ==> bc
Step four ==> abc
Step five ==> cba
Step six
==> d
Step seven ==> dcba
D:/bonin/rubyScript/code/turnround.rb:101:in
‘invert’: stack level too deep (SystemStackError)
from D:/bonin/rubyScript/code/turnround.rb:111:
in ‘invert’
2.18 Simple Continuation
Script continuation.rb
Remark: The shift method returns the first element of an array and
removes it (shifting all other elements down by one). It returns nil if the
array is empty.
RU
callcc
The continuation objects hold a return address and execution context, allowing a nonlocal return to the end of the callcc block from anywhere
within a program. The instance method call invokes the continuation.
The program continues from the end of the callcc block. If no arguments are given, the original callcc returns nil. If one argument is given,
callcc returns it. Otherwise, an array containing args is returned.
#
# Simple continuation example
#
2.19. CALLING FUTURE CODE
H
35
AC
# Hinrich Bonin
# 13-Dec-2003
#
x = [ "one", "two", "three", "four", "five", "six" ]
callcc{|$mycc|
puts "Begin of the block"
puts "Doing this block"
puts "End of the block"}
puts "Working!"
puts(value = x.shift)
CO
$mycc.call unless value =˜ /four/ # continues of
# the end of the
# callcc
puts "End of the program"
# EOF 193.174.33.66 D:/bonin/rubyScript/code/continuation.rb
Protocol continuation.log
d:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
BY
d:\bonin\rubyScript\code>continuation
Begin of the block
Doing this block
End of the block
Working!
one
Working!
two
Working!
three
Working!
four
End of the program
d:\bonin\rubyScript\code>
2.19 Calling Future Code
Script future.rb
#
# Calling future code
#
# Hinrich Bonin
# 13-Dec-2003
#
foo = 7
$bar = 0
def h(n)
callcc{|$mycc|
print "Function h ==> ", n, "\n"
n = n + 1
}
end
CO
def g(n)
print "Function g ==> ", n, "\n"
n = n + 1
end
AC
H
KAPITEL 2. EXAMPLES AND EXERCISES
36
def f(n)
$bar = $bar + 1
print "Function f ==> ", n, "\n"
n = n + 1
end
puts f(g(h(foo)))
BY
print "$bar == " , $bar, "\n"
$mycc.call 4 unless $bar == 5
# EOF 193.174.33.66 D:/bonin/rubyScript/code/future.rb
Protocol future.log
d:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
D:\bonin\rubyScript\code>future
Function h ==> 7
Function g ==> 8
Function f ==> 9
10
$bar == 1
Function g ==> 4
Function f ==> 5
==> 4
==> 5
==> 4
==> 5
AC
==> 4
==> 5
CO
6
$bar == 2
Function g
Function f
6
$bar == 3
Function g
Function f
6
$bar == 4
Function g
Function f
6
$bar == 5
H
2.20. CGI (COMMON GATEWAY INTERFACE)
D:\bonin\rubyScript\code>
2.20 CGI (Common Gateway Interface)
Script MyCGI.rb
RU
BY
#
# Simple CGI example
#
# Hinrich Bonin
# 19-Dec-2003
#
require "cgi"
cgi = CGI.new("html4")
cgi.out{
cgi.html{
cgi.head{
cgi.title{"My CGI test"}
} +
cgi.body{
cgi.h1{"Common Gateway Interface"} +
cgi.form{
cgi.textarea("get_text") +
cgi.br +
cgi.submit
}
}
}
}
# EOF 193.174.33.66 D:/bonin/rubyScript/code/MyCGI.rb
37
Protocol MyCGI.log
AC
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
H
KAPITEL 2. EXAMPLES AND EXERCISES
38
D:\bonin\rubyScript\code>MyCGI nil=0 > ../html/MyCGI.html
D:\bonin\rubyScript\code>
HTML File MyCGI.html
Content-Type: text/html
Content-Length: 341
2.21 Quadric
BY
CO
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>My CGI test</TITLE>
</HEAD>
<BODY><H1>Common Gateway Interface</H1>
<FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">
<TEXTAREA NAME="get_text" ROWS="10" COLS="70">
</TEXTAREA>
<BR>
<INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
RU
“This program demonstrates the use of some of the gluQuadric routines.
Quadric objects are created with some quadric properties and the callback routine to handle errors. Note that the cylinder has no top or bottom
and the circle has a hole in it.” (→ /ruby/doc/samples/opengl/)
Script quadric.rbw
Remark: Source code → /ruby/doc/samples/opengl/quadric.rbw
# *
# * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
# */
2.21. QUADRIC
H
39
$startList = nil;
AC
#
#/*
# * quadric.c
# * This program demonstrates the use of some of the gluQuadric*
# * routines. Quadric objects are created with some quadric
# * properties and the callback routine to handle errors.
# * Note that the cylinder has no top or bottom and the circle
# * has a hole in it.
# */
require "opengl"
require "glut"
require "mathn"
CO
#void CALLBACK errorCallback(GLenum errorCode)
#{
#
const GLubyte *estring;
#
#
estring = gluErrorString(errorCode);
#
fprintf(stderr, "Quadric Error: %s\n", estring);
#
exit(0);
#}
BY
def init
mat_ambient = [ 0.5, 0.5, 0.5, 1.0 ];
mat_specular = [ 1.0, 1.0, 1.0, 1.0 ];
mat_shininess = [ 50.0 ];
light_position = [ 1.0, 1.0, 1.0, 0.0 ];
model_ambient = [ 0.5, 0.5, 0.5, 1.0 ];
GL.ClearColor(0.0, 0.0, 0.0, 0.0);
GL.Material(GL::FRONT, GL::AMBIENT, mat_ambient);
GL.Material(GL::FRONT, GL::SPECULAR, mat_specular);
GL.Material(GL::FRONT, GL::SHININESS, mat_shininess);
GL.Light(GL::LIGHT0, GL::POSITION, light_position);
GL.LightModel(GL::LIGHT_MODEL_AMBIENT, model_ambient);
RU
GL.Enable(GL::LIGHTING);
GL.Enable(GL::LIGHT0);
GL.Enable(GL::DEPTH_TEST);
#/* Create 4 display lists, each with a different quadric object.
# * Different drawing styles and surface normal specifications
# * are demonstrated.
# */
$startList = GL.GenLists(4);
qobj = GLU.NewQuadric();
#
#
KAPITEL 2. EXAMPLES AND EXERCISES
H
40
gluQuadricCallback(qobj, GLU_ERROR,
(GLvoid (CALLBACK*) ()) errorCallback);
AC
GLU.QuadricDrawStyle(qobj, GLU::FILL); #/* smooth shaded */
GLU.QuadricNormals(qobj, GLU::SMOOTH);
GL.NewList($startList, GL::COMPILE);
GLU.Sphere(qobj, 0.75, 15, 10);
GL.EndList();
GLU.QuadricDrawStyle(qobj, GLU::FILL); #/* flat shaded */
GLU.QuadricNormals(qobj, GLU::FLAT);
GL.NewList($startList+1, GL::COMPILE);
GLU.Cylinder(qobj, 0.5, 0.3, 1.0, 15, 5);
GL.EndList();
CO
GLU.QuadricDrawStyle(qobj, GLU::LINE); #/* all polygons wireframe */
GLU.QuadricNormals(qobj, GLU::NONE);
GL.NewList($startList+2, GL::COMPILE);
GLU.Disk(qobj, 0.25, 1.0, 20, 4);
GL.EndList();
GLU.QuadricDrawStyle(qobj, GLU::SILHOUETTE); #/* boundary only
GLU.QuadricNormals(qobj, GLU::NONE);
GL.NewList($startList+3, GL::COMPILE);
GLU.PartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0);
GL.EndList();
end
BY
display = Proc.new {
GL.Clear(GL::COLOR_BUFFER_BIT | GL::DEPTH_BUFFER_BIT);
GL.PushMatrix();
GL.Enable(GL::LIGHTING);
GL.ShadeModel(GL::SMOOTH);
GL.Translate(-1.0, -1.0, 0.0);
GL.CallList($startList);
RU
GL.ShadeModel(GL::FLAT);
GL.Translate(0.0, 2.0, 0.0);
GL.PushMatrix();
GL.Rotate(300.0, 1.0, 0.0, 0.0);
GL.CallList($startList+1);
GL.PopMatrix();
GL.Disable(GL::LIGHTING);
GL.Color(0.0, 1.0, 1.0);
GL.Translate(2.0, -2.0, 0.0);
GL.CallList($startList+2);
*/
2.21. QUADRIC
GL.PopMatrix();
GL.Flush();
}
AC
GL.Color(1.0, 1.0, 0.0);
GL.Translate(0.0, 2.0, 0.0);
GL.CallList($startList+3);
H
41
CO
reshape = Proc.new {|w, h|
GL.Viewport(0, 0, w, h);
GL.MatrixMode(GL::PROJECTION);
GL.LoadIdentity();
if (w <= h)
GL.Ortho(-2.5, 2.5, -2.5*h/w,
2.5*h/w, -10.0, 10.0);
else
GL.Ortho(-2.5*w/h,
2.5*w/h, -2.5, 2.5, -10.0, 10.0);
end
GL.MatrixMode(GL::MODELVIEW);
GL.LoadIdentity();
}
BY
#/* ARGSUSED1 */
keyboard = Proc.new {|key, x, y|
case (key)
when 27
exit(0);
end
}
RU
#int main(int argc, char** argv)
#{
GLUT.Init
GLUT.InitDisplayMode(GLUT::SINGLE | GLUT::RGB | GLUT::DEPTH);
GLUT.InitWindowSize(500, 500);
GLUT.InitWindowPosition(100, 100);
GLUT.CreateWindow($0);
init();
GLUT.DisplayFunc(display);
GLUT.ReshapeFunc(reshape);
GLUT.KeyboardFunc(keyboard);
GLUT.MainLoop();
#
return 0;
#}
Protocol quadric.log
D:\bonin\rubyScript>ruby --copyright
KAPITEL 2. EXAMPLES AND EXERCISES
BY
Legende: Source code → p. 38
CO
AC
H
42
Abbildung 2.2: Running quadric.rbw
ruby - Copyright (C) 1993-2003 Yukihiro Matsumoto
D:\bonin\rubyScript>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
D:\bonin\rubyScript>ruby ./code/quadric.rbw
RU
D:\bonin\rubyScript>
2.22 Biorhythm
Script biorhythm.rb
Remark: Source code → /ruby/doc/Ruby-1.8.0/samples/biorhythm.rb
2.22. BIORHYTHM
H
AC
biorhythm.rb $Release Version: $
$Revision: 1.9 $
$Date: 2003/05/05 14:02:14 $
by Yasuo OHBA(STAFS Development Room)
probably based on:
Newsgroups: comp.sources.misc,de.comp.sources.os9
From: [email protected] (Frank Kaefer)
Subject: v41i126: br - Biorhythm v3.0, Part01/01
Message-ID: <[email protected]>
Sender: [email protected] (Kent Landfield)
Organization: Sterling Software
Date: Tue, 1 Feb 1994 07:06:16 GMT
Posting-number: Volume 41, Issue 126
Archive-name: br/part01
Environment: basic, dos, os9
include
require
require
require
CO
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
43
Math
"date.rb"
"parsearg.rb"
"parsedate.rb"
:
:
:
:
:
:
use default values.\n"
use system date; use specified date.\n"
specifies your birthday.\n"
show values or graph.\n"
graph range (only in effect for graphs).\n"
help\n"
BY
def usage()
print "Usage:\n"
print "biorhythm.rb [options]\n"
print " options...\n"
print "
-D YYYYMMDD(birthday)
print "
--sdate | --date YYYYMMDD
print "
--birthday YYYYMMDD
print "
-v | -g
print "
--days DAYS
print "
--help
end
$USAGE = ’usage’
def printHeader(y, m, d, p, w)
print "\n>>> Biorhythm <<<\n"
printf "The birthday %04d.%02d.%02d is a %s\n", y, m, d, w
printf "Age in days: [%d]\n\n", p
end
RU
def getPosition(z)
pi = Math::PI
z = Integer(z)
phys = (50.0 * (1.0 + sin((z / 23.0 - (z / 23)) * 360.0 * pi / 180.0))).to_i
emot = (50.0 * (1.0 + sin((z / 28.0 - (z / 28)) * 360.0 * pi / 180.0))).to_i
geist =(50.0 * (1.0 + sin((z / 33.0 - (z / 33)) * 360.0 * pi / 180.0))).to_i
return phys, emot, geist
end
def parsedate(s)
ParseDate::parsedate(s).values_at(0, 1, 2)
end
KAPITEL 2. EXAMPLES AND EXERCISES
H
44
def name_of_week(date)
Date::DAYNAMES[date.wday]
end
(YYYYMMDD) : ")
CO
if $OPT_D
dd = Date.today
bd = Date.new(*parsedate($OPT_D))
ausgabeart = "g"
else
if $OPT_birthday
bd = Date.new(*parsedate($OPT_birthday))
else
STDERR.print("Birthday
unless (si = STDIN.gets.chop).empty?
bd = Date.new(*parsedate(si))
end
end
if !bd
STDERR.print "BAD Input Birthday!!\n"
exit()
end
AC
#
# main program
#
parseArgs(0, nil, "vg", "D:", "sdate", "date:", "birthday:", "days:")
BY
if $OPT_sdate
dd = Date.today
elsif $OPT_date
dd = Date.new(*parsedate($OPT_date))
else
STDERR.print("Date
[<RETURN> for Systemdate] (YYYYMMDD) : ")
unless (si = STDIN.gets.chop).empty?
dd = Date.new(*parsedate(si))
end
end
dd ||= Date.today
RU
if $OPT_v
ausgabeart = "v"
elsif $OPT_g
ausgabeart = "g"
else
STDERR.print("Values for today or Graph (v/g) [default g] : ")
ausgabeart = STDIN.gets.chop
end
end
if ausgabeart == "v"
printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))
print "\n"
phys, emot, geist = getPosition(dd - bd)
printf "Biorhythm:
%04d.%02d.%02d\n", dd.year, dd.month, dd.day
printf "Physical:
%d%%\n", phys
printf "Emotional:
%d%%\n", emot
2.22. BIORHYTHM
H
45
AC
printf "Mental:
%d%%\n", geist
print "\n"
else
if $OPT_days
display_period = $OPT_days.to_i
elsif $OPT_D
display_period = 9
else
STDERR.printf("Graph for how many days
[default 10] : ")
display_period = STDIN.gets.chop
if display_period.empty?
display_period = 9
else
display_period = display_period.to_i - 1
end
end
CO
printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))
print "
P=physical, E=emotional, M=mental\n"
print "
-------------------------+-------------------------\n"
print "
Bad Condition
|
Good Condition\n"
print "
-------------------------+-------------------------\n"
(dd - bd).step(dd - bd + display_period) do |z|
phys, emot, geist = getPosition(z)
BY
printf "%04d.%02d.%02d : ", dd.year, dd.month, dd.day
p = (phys / 2.0 + 0.5).to_i
e = (emot / 2.0 + 0.5).to_i
g = (geist / 2.0 + 0.5).to_i
graph = "." * 51
graph[25] = ?|
graph[p] = ?P
graph[e] = ?E
graph[g] = ?M
print graph, "\n"
dd = dd + 1
end
print "
-------------------------+-------------------------\n\n"
end
Protocol biorhythm.log
D:\bonin\rubyScript\code>ruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
RU
D:\bonin\rubyScript\code>biorhythm --help
Usage:
biorhythm.rb [options]
options...
-D YYYYMMDD(birthday)
: use default values.
--sdate | --date YYYYMMDD : use system date; use specified date.
--birthday YYYYMMDD
: specifies your birthday.
-v | -g
: show values or graph.
--days DAYS
: graph range (only in effect for graphs).
--help
: help
>>> Biorhythm <<<
The birthday 1945.05.08 is a Tuesday
Age in days: [21390]
:
:
:
:
:
:
:
:
:
:
P=physical, E=emotional, M=mental
-------------------------+------------------------Bad Condition
|
Good Condition
-------------------------+------------------------..............E..........P......................M..
...................E.....|......P................M.
.........................E............P...........M
.........................|.....E...........P......M
.........................|..........E..........P.M.
.........................|...............E.....M.P.
.........................|..................ME....P
.........................|..............M.......EP.
.........................|..........M........P...E.
.........................|......M........P........E
-------------------------+-------------------------
D:\bonin\rubyScript\code>
CO
2003.11.30
2003.12.01
2003.12.02
2003.12.03
2003.12.04
2003.12.05
2003.12.06
2003.12.07
2003.12.08
2003.12.09
AC
D:\bonin\rubyScript\code>biorhythm -D 19450508 --sdate -v
H
KAPITEL 2. EXAMPLES AND EXERCISES
46
2.23 WIN32OLE — Internetexplorer
BY
Methods that aren’t known to WIN32OLE (such as visible or gohome)
are passed on to the WIN32OLE#invoke method, which sends the
proper commands to the server.
Script internetexplorer.rbw
RU
#
# A fresh copy of Internet Explorer
#
# Hinrich Bonin
# 12-Dec-2003
#
require ’win32ole’
ie = WIN32OLE.new(’InternetExplorer.Application’)
ie.visible = true
ie.gohome
# EOF 193.174.33.66 D:/bonin/rubyScript/code/internetexplorer.rbw
Protocol internetexplorer.log
d:\bonin\rubyScript\code>irb --version
irb 0.9(02/07/03)
d:\bonin\rubyScript\code>irb
BY
CO
AC
H
2.23. WIN32OLE — INTERNETEXPLORER
Legende: Source code → p. 42
RU
Abbildung 2.3: Running biorhythm.rb
47
H
KAPITEL 2. EXAMPLES AND EXERCISES
48
d:\bonin\rubyScript\code>internetexplorer
d:\bonin\rubyScript\code>
2.24 WIN32OLE — Excel
AC
irb(main):001:0> require ’win32ole’
=> true
irb(main):002:0> WIN32OLE::VERSION
=> "0.5.4"
irb(main):003:0> exit
#
# Using Microsoft Excel
#
# Hinrich Bonin
# 12-Dec-2003
#
require ’win32ole’
CO
Script excel.rbw
Remark: Source code idea → /ruby/ProgrammingRuby.chm,
section: Ruby and Microsoft Windows, Windows Automation, An Example
# -4100 is the value for the Excel constant xl3DColumn.
ChartTypeVal = -4100;
# Create the chart
BY
# Creates OLE object to Excel
excel = WIN32OLE.new("excel.application")
excel[’Visible’] = TRUE;
workbook = excel.Workbooks.Add();
excel.Range("a1")[’Value’] = 3;
excel.Range("a2")[’Value’] = 2;
excel.Range("a3")[’Value’] = 1;
excel.Range("a1:a3").Select();
excelchart = workbook.Charts.Add();
excelchart[’Type’] = ChartTypeVal;
RU
# EOF 193.174.33.66 D:/bonin/rubyScript/code/excel.rbw
Protocol excel.log
d:\bonin\rubyScript\code>irb --version
irb 0.9(02/07/03)
d:\bonin\rubyScript\code>irb
irb(main):001:0> require ’win32ole’
=> true
2.24. WIN32OLE — EXCEL
CO
AC
H
49
Legende: Source code → p. 48
Abbildung 2.4: Running excel.rbw
BY
irb(main):002:0> WIN32OLE::VERSION
=> "0.5.4"
irb(main):003:0> exit
d:\bonin\rubyScript\code>excel
RU
d:\bonin\rubyScript\code>
BY
CO
AC
H
KAPITEL 2. EXAMPLES AND EXERCISES
RU
50
H
AC
Kapitel 3
CO
Software Engineering Tools
3.1 ri — Ruby Information at your fingertips
Ruby information at your fingertips (ri) displays documentation for
the named classes or methods. All names can be abbreviated to their
minimum non-ambiguous size. The program files ri and refdoc.rb
are copyright (c) 2001 Dave Thomas, The Pragmatic Programmers, and
are released under the same terms as Ruby.
D:\bonin\rubyScript>ri --version
ri 1.8a
BY
D:\bonin\rubyScript>ri Bignum
This is a test ’ri’. Please report errors and omissions
on http://www.rubygarden.org/ruby?RIOnePointEight
RU
------------------------------------------------------class: Bignum < Integer
------------------------------------------------------Bignum objects hold integers outside the range
of Fixnum. Bignum
objects are created automatically when integer
calculations would
otherwise overflow a Fixnum. When a calculation
involving Bignum
objects returns a result that will fit in a Fixnum,
the result is automatically converted.
For the purposes of the bitwise operations and [],
a Bignum is treated as if it were an infinite-length
bitstring with 2’s complement representation.
While Fixnum values are immediate, Bignum objects are
not---assignment and parameter passing work
with references to objects, not the objects
51
ri
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
CO
AC
H
52
Legende: Simple examble in the Interactive Ruby Shell.
themselves.
BY
Abbildung 3.1: irb — Interactive Ruby Shell
RU
------------------------------------------------------<=>, ==, Arithmeticoperations, Bitoperations,
[], abs, div, divmod,
eql?, modulo, quo, remainder, size, to_f, to_s
------------------------------------------------------D:\bonin\rubyScript>
3.2 irb — Interactive Ruby Shell
The Ruby module irb lets you enter Ruby programs interactively and
see the results immediately. The figure 3.1 p. 52 shows a simple example.
3.3. RUBY-MODE — EMACS MODE
BY
CO
AC
H
53
Legende: Ruby file Hound.rb in editor GNU Emacs 21.2.1.
Abbildung 3.2: ruby-mode — Editor Emacs
3.3 ruby-mode — Emacs Mode
RU
1. Step: load-library C:\Programme\ruby\lib\ruby-mode.el
Remark: You type ESC , than x and than the characters above.
2. Step: enable ruby-mode
Remark: You type ESC , than x and than ruby-mode.
The figure 3.2 p. 53 shows a simple example.
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
BY
CO
AC
H
54
Legende: RDtool file Hound.rd in editor GNU Emacs 21.2.1.
Abbildung 3.3: rd-mode — Editor Emacs
3.4 rd-mode — Emacs Mode
The figure 3.3 p. 54 shows a simple example. Installing rd2 → section 3.8 p. 57.
RU
1. Step Copying rd-mode.el into the Emacs lib-path, for example:
D:\bonin\rubyScript\rdtool\rdtool-0.6.14\utils\rd-mode.el
into:
C:\Programme\ruby\lib\
2. Step Updating the Emacs load file emacs, for example: C:_emacs
with the following lines:
55
H
3.5. ERUBY — EMBEDDING RUBY IN HTML
AC
;; Unterstützung für rd-mode
(setq load-path (cons "c:/programme/ruby/lib/" load-path))
(require ’rd-mode)
3. Step: enable rd-mode
Remark: You type ESC , than x and than rd-mode.
3.5 eruby — Embedding Ruby in HTML
Protocol myeruby.log
CO
D:\bonin\rubyScript>eruby --version
ruby 1.8.0 (2003-08-04) [i386-mswin32]
eRuby version 1.0.4
D:\bonin\rubyScript>eruby < ./html/myinput.erb > ./html/myoutput.html
D:\bonin\rubyScript>
Input file myinput.erb
RU
BY
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Hinrich Bonin 15-Dec-2003
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>My eRuby</title>
</head>
<body>
<p>eRuby is <% n = 100; print "#{n}% scripting fun!" %></p>
</body>
</html>
Output file myoutput.html
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Hinrich Bonin 15-Dec-2003
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
3.6 Framework Ruby on Rails
Ruby on Rails (RoR1 ) is a full-stack framework for developing databasebacked web applications according to the Model-View-Control pattern.
RoR takes full advantage of Ruby. RoR has two guiding principles:
CO
RoR
AC
<head>
<title>My eRuby</title>
</head>
<body>
<p>eRuby is 100% scripting fun!</p>
</body>
</html>
H
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
56
1. less software and
Less software means the programmer writes fewer lines of code
to implement an application. Keeping the code small means faster
development and fewer bugs.
RoR was created by David Heinemeier Hansson in July 2004. RoR is an
open source Web 2.0-Framework released under MIT license. RoR is all
about infrastructure so it’s a great fit for practically any type of web application — software for collaboration, community, e-commerce, content
management, statistics etc. (→ http://www.rubyonrails.org/,
visited 22-Apr-2007)
3.7 Eclipse — Plug-In
RU
Web 2.0
BY
2. Convention over Configuration.
Convention over configuration means an end to verbose XML
configuration files — there aren’t any in Rails! Instead of configuration files, a Rails application uses a few simple programming
conventions that allow it to figure out everything through reflection and discovery. The application code and the running database
already contain everything that Rails needs to know.
Eclipse consits of the following key components (→ [Gamma / Beck, 2004]
p. 6.):
• Core:
1
German: ≈ Ruby auf dem rechten Weg
3.8. RD2 — FORMATER TOOL
H
57
Eclipse Architecture
PDE (Plug-In Development Environment)
AC
JDT (Java Development Tools)
Platform
Legende:
PDE
CO
extends the JDT with the support for developing plugins.
JDT add a full-featured Java IDE to Eclipse
Platform defines the common programming-language-neutral infrastructure.
Source → [Gamma / Beck, 2004] p. 5.
Tabelle 3.1: Eclipse — The Three Layers
– The run-time component defines the plug-in infrastructure.
It discovers the available plug-ins on start-up and manages
the plug-in loading.
Runtime
– A workspace manages one or more top-level projects. A project consits of file and folders that map onto the underlying
file system.
Workspace
BY
• UI (User Interface):
SWT
– JFace — A set of smaller UI frameworks built on top of
SWT supporting common UI tasks.
JFace
– The workbench defines the Eclipse UI paradigm. It centers
around editors, views, and perspectives.
Workbench
RU
– The SWT (Standard Widget Toolkit) provides graphics and
define a standard set of widgets.
3.8 rd2 — formater tool
Installing the formater tool rd2 on Windows:
→ http://www.dets-home.de/it-writings/Install rd2 winnt.html
(online 19-Dec-2003).
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
BY
CO
AC
H
58
Legende:
Ruby Plug-Ins (org.rubypeople.rdt.core (0.3.2) etc., copyright RubyPeople, Inc. 2002) in Eclipse Platform (version 2.1.1).
RU
Abbildung 3.4: ruby-plug-ins — Eclipse
3.8. RD2 — FORMATER TOOL
BY
CO
AC
H
59
Legende:
Script prime.rb →p. 11 in Eclipse Platform (version 2.1.1).
RU
Abbildung 3.5: Script prime.rb — Eclipse
H
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
60
3.8.1 Prerequisite racc tool
AC
The tool racc is a LALR(1) parser generator. It is written in Ruby
itself, and generates Ruby program. For Ruby 1.8.0: Take racc for
Windows from:
ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/racc-1.4.4-all-i386-mswin32-1.8.zip
(online 19-Dec-2003)
Extract this archive in a temporary directory (below referred to as instsrc)
racc.bat
1. Copy racc.bat from directory instsrc/bin to $ruby home/bin
2. Goto instsrc/lib/ruby/site ruby/1.8
4. Goto instsrc/doc/ruby
CO
3. Copy directory racc to $ruby home/lib/ruby/site ruby/1.8
5. Copy subdir racc-1.4.4-all to $ruby home/doc/ruby
To test it, type:
d:\bonin\rubyScript>racc --version
racc version 1.4.4
d:\bonin\rubyScript>
BY
3.8.2 rdtool — Installation
Fetch the rdtool tarball (e. g. rdtool-0.6.11.tar.gz) from:
http://www.ruby-lang.org/en/raa-list.rhtml?name=RDtool (online 19-Dec-2003)
and extract it in a temporary directory (in the following referred to as
instsrc).
1. Open a DOS-box (cmd.exe) and go to instsrc
RU
rd2.bat
2. Execute: racc rd/rdblockparser.ry
Note: Your $ruby home/bin should be in your path, then racc
will be found.
3. Execute: racc rd/rdinlineparser.ry
4. Copy the directory instsrc/rd to
$ruby home/lib/ruby/site ruby/1.8
5. Copy the file ../rd2 to $ruby home/bin
3.8. RD2 — FORMATER TOOL
H
61
6. Goto $ruby home/bin and create a file rd2.bat containing:
AC
@echo off
"$ruby_home\bin\ruby.exe"
"$ruby_home\bin\rd2" %1 %2 %3 %4 %5 %6 %7 %8 %9
(Note: You have to replace $ruby home with the actual path to
your Ruby installation).
To test it, copy a rd-file, open the DOS-Box, go to this directory and
call:
CO
D:\bonin\rubyScript>rd2 --version
RDtool -- rd2 0.6.13
RDtool Framework -- Document Tree 0.6.13
RDtool Framework -- Visitor 0.6.13
D:\bonin\rubyScript>rd2 ./code/Hound.rd > ./html/Hound.html
D:\bonin\rubyScript>
RD-File Hound.rd
RU
BY
#
# Simple inheritance example
#
# Hinrich Bonin
# 3-Dec-2003
#
=begin
= My Hound Application
== Written in Ruby
=== A Simple rd2 Example
==== H. Bonin 3-Dec-2003
Ruby-Example with
* inheritance
* String
** super
** #{@xxx}
class Mammal
def initialize(name,sex)
@name = name
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
H
62
AC
@sex = sex
end
def to_s
"#{@name} (#{@sex})"
end
end
CO
class Hound < Mammal
def initialize(name,sex,performance,race)
super(name,sex)
@performance = performance
@race = race
end
def to_s
"Hound: " +
"#{@race} " +
super +
" --- #{@performance}"
end
end
elsa = Hound.new("Elsa vom Erlenbruch", "male" ,
"SWI", "German Setter")
puts(elsa.to_s)
BY
# EOF 193.174.33.66 D:/bonin/rubyScript/code/Hound.rb
=end
Produced HTML-File Hound.html
RU
<?xml version="1.0" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled</title>
</head>
<body>
<h1><a name="label-0" id="label-0">My Hound Application</a></h1>
<!-- RDLabel: "My Hound Application" -->
<h2><a name="label-1" id="label-1">Written in Ruby</a></h2>
<!-- RDLabel: "Written in Ruby" -->
<h3><a name="label-2" id="label-2">A Simple rd2 Example</a></h3>
<!-- RDLabel: "A Simple rd2 Example" -->
63
H
3.9. DYBASE — OBJECT ORIENTED DBMS
BY
CO
AC
<h4><a name="label-3" id="label-3">H. Bonin 3-Dec-2003</a></h4>
<!-- RDLabel: "H. Bonin 3-Dec-2003" -->
<p>Ruby-Example with</p>
<ul>
<li>inheritance</li>
<li>String</li>
<li>* super</li>
<li>* #{@xxx}</li>
</ul>
<p>class Mammal</p>
<pre>def initialize(name,sex)
@name = name
@sex = sex
end
def to_s
"#{@name} (#{@sex})"
end</pre>
<p>end</p>
<p>class Hound &lt; Mammal</p>
<pre>def initialize(name,sex,performance,race)
super(name,sex)
@performance = performance
@race = race
end
def to_s
"Hound: " +
"#{@race} " +
super +
" --- #{@performance}"
end</pre>
<p>end</p>
<p>elsa = Hound.new("Elsa vom Erlenbruch", "male" ,</p>
<pre>"SWI", "German Setter")</pre>
<p>puts(elsa.to_s)</p>
RU
</body>
</html>
3.9 DyBASE — Object Oriented DBMS
DyBASE2 is very simple OODBMS (Object Oriented Database Man2
DyBASE Web-Site: http://www.garret.ru/k̃nizhnik online 18-Dec2003
OODBMS
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
BY
CO
AC
H
64
RU
Legende:
Script Hound.rd →p. 61 applied to RDtool rd2 (version 0.6.13).
Abbildung 3.6: Script Hound.rd — rd2
65
H
3.9. DYBASE — OBJECT ORIENTED DBMS
AC
agement System for languages with dynamic type checking. The specific
of such languages is that types of class instance variables are not known
at compiler time. Moreover the same instance variable can be used to
store integers and string and later be assigned reference to some other
object. So it means that database could not keep information about object format in class descriptor and should store type for each instance
variable. DyBASE provides APIs to the most popular scripting languages with OO extensions: PHP, Ruby and Python.
Add to your ruby-path the fowllowing files:
CO
C:\Programme\ruby\bin\dybasedll.dll
C:\Programme\ruby\lib\ruby\1.8\dybase.rb
C:\Programme\ruby\lib\ruby\1.8\dybaseapi.dll
from the download file dybase-013.zip.
3.9.1 Application Program Interface
Persistent class
Persistent class is common root for all persistent capable objects. It provides method for
loading and storing object.
load() Explicitly load object. This method check if objects needs to be loaded,
and if so load it from the storage.
BY
isLoaded() Check if object is already loaded or explicit invocation of load()
method is required. Returns: True if object is loaded, False otherwise
isPersistent() Check if object is persistent (was assigned persistent OID).
Returns: True if object is persistent, False otherwise
isModified() Check if object was modified during current transaction Returns: True if modify method was invoked for the object within current transaction,
False otherwise
RU
store() Store the object in the storage. If object is not yet persistent it is first made persistent by assigning persistent OID. If object references some other non-persistent
object then they recursively made persistent and also stored in the storage. But referenced persistent objects are not recursively stored. You should invoke store method
explicitly for each changed persistent object.
modify() Mark object as modified. This object will be automatically stored to
the database during transaction commit.
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
H
66
getStorage() Get storage in which object is stored. Returns: Storage in which
object is stored or Null if object is not persistent.
deallocate() Deallocate object in the storage. This method doesn’t affect
AC
instance of the object in application memory — it is deallocated in normal way by
language runtime. If you are using garbage collector, there is no need in invocation of
this method.
CO
sharedLock(nowait=false) Lock persistent object in shared mode.
Other threads will be able to set their shared locks on this objects, but not exclusive
lock can be set until this lock is released. Upgrading of the lock is not possible (thread
having read lock can not upgrade it to exclusive lock). It is done to prevent possible
deadlocks caused by lock updates. But locks are reentrant - so thread can request the
same lock many times (and correspondent number of unlocks is needed to release the
lock). Locking the object doesn’t prevent other threads from accessing the object — it
only has influence on sharedLock and exclusiveLock methods. So programmer should
set proper lock before accessing the object in multithreaded application. If object is
concurrently accessed by several threads in read-only mode, then explicit locking of
this object is not needed, because language API provides consistent retrieving of objects itself. Only persistent object (object which were assigned to the storage either
implicitly by saving some other persistent object referencing this object, either explicitly by Storage.makeObjectPersistent method. Parameters nowait — optional
parameter specifying whether request should wait until lock is available or fail if lock
can not be granted immediately. Returns: true if lock is successfully granted false
if lock can not be granted within specified time.
RU
BY
exclusiveLock(nowait=false) Lock persistent object in exclusive
mode. Only one thread can lock object in exclusive mode at each moment of time. Shared or exclusive lock requests of other threads will be blocked until this lock is released.
shared locks on this objects, but not exclusive lock can be set until this lock is released.
This lock is reentrant, so thread owning the lock can successfully retrieve the lock many
times (and correspondent number of unlocks is needed to release the lock). Locking the
object doesn’t prevent other threads from accessing the object - it only has influence on
sharedLock and exclusiveLock methods. So programmer should set proper lock before
accessing the object in multithreaded application. Only persistent object (object which
were assigned to the storage either implicitly by saving some other persistent object
referencing this object, either explicitly by Storage.makeObjectPersistent method. Parameters nowait — optional parameter specifying whether request should wait until
lock is available or fail if lock can not be granted immediately. Returns: true if lock is
successfully granted false if lock can not be granted within specified time.
unlock() Remove granted lock. If lock was requested several times by one thread,
then correspondent number of unlocks is needed to release the lock.
Index class The index class provides access to the objects by key. Keys of
any scalar or string type are supported. But in one index can contains keys only of
one type. Index class extends Persistent class and so it is normal Persistent
object. Index can be unique (duplicated keys are prohibited) or not unique.
67
H
3.9. DYBASE — OBJECT ORIENTED DBMS
drop() Delete index. This method removes all entries from index and deallocate
index object.
clear() Remove all entries from the index. This method doesn’t deallocate in-
AC
dexed objects.
insert(key, value) Insert object in index. Parameters key — key with
type matching with type of the index value — persistent capable object to be associated
with this key. This object is automatically made persistent (if it isn’t persistent yet).
Returns: true if object was successfully inserted in index, false if index is unique
and such key already exists in index.
CO
set(key, value) Set object for the specified key. If such key already exists
in the index, previous association of this key will be replaced. Parameters key — key
with type matching with type of the index value — persistent capable object to be associated with this key. This object is automatically made persistent (if it isn’t persistent
yet).
remove(key, value=Null) Remove object from index. Parameters key
— key with type matching with type of the index value — optional reference to the persistent object removed from the index. If index is unique, this parameter can be skipped.
Returns: true if object was successfully removed from the index, false if there is no
object with such key in index.
BY
get(key) Get object associated with specified key. Parameters key — key with
type matching with type of the index. Returns: Null if there is no object with such key
in the index, object itself if there is only one object with such key in the index, array of
object if there are more than one object with such key in the index
find(low=null, lowInclusive=true, high=null, highInclusive=true) Get objects which keys belongs to the specified range. Parameters low —
low boundary for key value, if Null than there is no low boundary. lowInclusive —
if low boundary is inclusive or not high — high boundary for key value, if Null than
there is no high boundary. highInclusive — if high boundary is inclusive or not
Returns: Array of selected objects or Null if there are no object with key belonging to
the specified range
iterator(low=null, lowInclusive=true, high=null,
highInclusive=true, ascent=true) Get iterator for objects in
RU
the index. Objects will be traversed in key ascending order. Details of iterator’s implementation depends on particular language. Parameters low — low boundary for key
value, if Null than there is no low boundary. lowInclusive — if low boundary is
inclusive or not high — high boundary for key value, if Null than there is no high
boundary. highInclusive — if high boundary is inclusive or not ascent — iteration
order: if true, then objects will be traversed in key ascending order Returns: Usually this
method returns iterator object, but in some languages it is possible to pass block of code
which will be executed for each selected object.
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
H
68
Storage class
AC
Storage is class is the main class of DyBASE API. It provides access to the database
storage.
Storage(pagePoolSize = 4*1024*1024, objectCacheSize = 1000) Storage constructor. Parameters pagePoolSize — database
page pool in bytes (larger page pool usually leads to better performance) objectCacheSize — this parameter is used only by some of languages API and specify
maximal number of objects in application object cache. Not all languages APIs maintain such cache. Returns: Storage object. It is not opened and you should invoke open
method explicitly.
CO
open(path) Storage constructor. Parameters path — path to the database file
Returns: true if storage is successfully opened, false otherwise. Some language
APIs do not return false, but throw exception in case of failure.
close() Close the storage. If there is opened transaction, it will be first committed.
commit() Commit current transaction. Transaction is automatically started once
you update the database first time.
BY
rollback() Rollback current transaction. All changes done by current transaction are undone. Attention! Rollback of transaction did not restore original values of
application objects. It just clears object cache. You should not use any variable referencing persistent object after rollback, but instead of it use Storage.getRootObject method
and traverse objects from the root.
getRootObject() Get storage root object. Returns: Loaded storage root object or Null if root was not yet specified.
setRootObject(root) Specify new storage root object. Previous root object (if exists) is NOT deallocated. Parameters: root — new storage root object which
is automatically made persistent.
RU
deallocateObject(obj) Deallocate persistent object from the storage.
If object is not persistent, this method has no effect. Parameters: obj — persistent
object.
makeObjectPeristent(obj) Explicitly make object persistent. Object
is automatically made persistent when persistent object containing reference to this object is stored (persistency by reachability). But sometimes you may need to force assignment OID and storage reference to the object. It can be done by makePerisistent
method. This method doesn’t actually store object in the storage, just assign OID to it.
Parameters: obj — object to be made persistent, if it is already persistent = method as
no effect.
69
H
3.9. DYBASE — OBJECT ORIENTED DBMS
AC
This method is usually invoked by Persistent.store() method. storeObject(obj) Make object persistent if it is not yet persistent and store it in the storage.
Parameters: obj — stored object.
This method is usually invoked by Persistent.modify() method. modifyObject(obj) Mark object as modified. This object will be automatically stored to
the database during transaction commit. Parameters: obj - modified object.
loadObject(obj) Load object from the storage. This method is usually invoked by Persistent.load() method. Parameters: obj — loaded object.
CO
createStrIndex(unique = True) Create index for keys of string
type. Parameters: unique — whether duplicated keys are allowed or not (by default
not allowed) Returns: Index object
createIntIndex(unique = True) Create index for keys of integer
type. Parameters: unique — whether duplicated keys are allowed or not (by default
not allowed) Returns: Index object
createLongIndex(unique = True) Create index for keys of long
integer type. Not all languages supports long (64-bit integer) type and so do not provide
such method. Parameters: unique — whether duplicated keys are allowed or not (by
default not allowed) Returns: Index object
BY
createBoolIndex(unique = True) Create index for keys of boolean type. Not all languages supports boolean type and so do not provide such method.
Parameters: unique — whether duplicated keys are allowed or not (by default not
allowed) Returns: Index object
createRealIndex(unique = True) Create index for keys of floating point type. Parameters: unique — whether duplicated keys are allowed or not (by
default not allowed) Returns: Index object
RU
resetHash() Reset object hash. Each fetched object is stored in objByOidMap
hash table. It is needed to provide OID-¿instance mapping. Since placing object in hash
increase its access counter, such object can not be deallocated by garbage collector. So
after some time all persistent objects from the storage will be loaded to the memory.
To solve the problem almost all languages with implicit memory deallocation (garbage collection) provides weak references. But in some of them weak references are not
supported and sometime implementation of weak references is very inefficient. So to
prevent memory overflow you should use resetHash() method. This method just
clear hash table. After invocation of this method, you should not use any variable referencing persistent objects. Instead you should invoke getRootObject method and access
all other persistent objects only through the root.
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
H
70
AC
gc() Explicit start of garbage collector. Garbage collector will collect only committed object, so there is no need to invoke garbage collector more than once within
one transaction. Garbage collection can be used together with explicit deallocator by
Persistent.deallocate method. But when you are using garbage collector, you should be
careful with keeping references to the persistent objects in local variables. If there are
no references to such object from other persistent object (so it is not reachable from root
object), then garbage collector can deallocate such object. If you then try to access or
update this object using reference stored in local variable, you will get on error.
CO
setGcThreashold(maxAllocatedDelta) Set garbage collection
threshold. By default garbage collection is disable (threshold is set to 0). If it is set to
non zero value, GC will be started each time when delta between total size of allocated
and deallocated objects exceeds specified threshold OR after reaching end of allocation
bitmap in allocator. Parameters: maxAllocatedDelta — delta between total size of
allocated and deallocated object since last GC or storage opening
BY
sharedLock(obj, nowait=false) Lock object in shared mode. Other
threads will be able to set their shared locks on this objects, but not exclusive lock can be
set until this lock is released. Upgrading of the lock is not possible (thread having read
lock can not upgrade it to exclusive lock). It is done to prevent possible deadlocks caused by lock updates. But locks are reentrant - so thread can request the same lock many
times (and correspondent number of unlocks is needed to release the lock). Locking the
object doesn’t prevent other threads from accessing the object - it only has influence on
sharedLock and exclusiveLock methods. So programmer should set proper lock before
accessing the object in multithreaded application. If object is concurrently accessed by
several threads in read-only mode, then explicit locking of this object is not needed, because language API provides consistent retrieving of objects itself. Parameters: obj —
locked object nowait — optional parameter specifying whether request should wait
until lock is available or fail if lock can not be granted immediately. Returns: true if
lock is successfully granted false if lock can not be granted within specified time.
RU
exclusiveLock(obj, nowait=false) Lock object in exclusive mode. Only one thread can lock object in exclusive mode at each moment of time. Shared
or exclusive lock requests of other threads will be blocked until this lock is released.
shared locks on this objects, but not exclusive lock can be set until this lock is released.
This lock is reentrant, so thread owning the lock can successfully retrieve the lock many
times (and correspondent number of unlocks is needed to release the lock). Locking the
object doesn’t prevent other threads from accessing the object — it only has influence
on sharedLock and exclusiveLock methods. So programmer should set proper lock
before accessing the object in multithreaded application. Parameters: obj — locked object nowait — optional parameter specifying whether request should wait until lock
is available or fail if lock can not be granted immediately. Returns: true if lock is
successfully granted false if lock can not be granted within specified time.
unlock(obj) Remove granted lock. If lock was requested several times by one
thread, then correspondent number of unlocks is needed to release the lock. Parameters:
obj — unlocked object.
3.9.2 Example TestLink.rb
H
3.9. DYBASE — OBJECT ORIENTED DBMS
#!/usr/local/bin/ruby
AC
Source Code in the download file dybase-013.zip.
=begin
= Example: Supplier-Order-Detail database
This example illustrates usage
of one-to-many link in dybase
=end
require "dybase"
include Dybase
CO
def input(prompt)
begin
print(prompt)
s = gets()
if s == nil
break
end
s = s.strip()
end until s.length != 0
s
end
BY
class Detail<Persistent
def initialize(name, weight, color)
@name = name
@color = color
@weight = weight
@orders = []
end
attr_reader :name, :color, :weight, :orders
end
RU
class Supplier<Persistent
def initialize(name, address)
@name = name
@address = address
@orders = []
end
attr_reader :name, :address, :orders
end
class Order<Persistent
def initialize(detail, supplier, quantity, price)
71
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
H
72
@detail = detail
@supplier = supplier
@quantity = quantity
@price = price
end
db = Storage.new
if db.open(’testlist.dbs’)
root = db.getRootObject()
if root == nil
root = Root.new(db)
db.setRootObject(root)
end
CO
class Root<Persistent
def initialize( db)
@suppliers = db.createStrIndex
@details = db.createStrIndex
end
attr_reader :suppliers, :details
end
AC
end
attr_reader :detail, :supplier, :quantity, :price
RU
BY
while true
puts ’------------------------------------------’
puts ’1. Add supplier’
puts ’2. Add detail’
puts ’3. Add order’
puts ’4. Search suppliers’
puts ’5. Search details’
puts ’6. Suppliers of detail’
puts ’7. Deails shipped by supplier’
puts ’8. Exit’
cmd = input(’> ’)
if cmd == ’1’
name = input(’Supplier name: ’)
address = input(’Supplier address: ’)
supplier = Supplier.new(name, address)
root.suppliers.insert(name, supplier)
db.commit()
elsif cmd == ’2’
name = input(’Detail name: ’)
weight = input(’Detail weight: ’).to_f
color = input(’Detail color: ’)
detail = Detail.new(name, weight, color)
root.details.insert(name, detail)
db.commit()
H
3.9. DYBASE — OBJECT ORIENTED DBMS
73
RU
BY
CO
AC
elsif cmd == ’3’
supplierName = input(’Supplier name: ’)
supplier = root.suppliers.get(supplierName)
if supplier == nil
puts ’No such supplier’
retry
end
detailName = input(’Detail name: ’)
detail = root.details.get(detailName)
if detail == nil
puts ’No such detail’
retry
end
quantity = input(’Quantity: ’).to_i
price = input(’Price: ’).to_i
order = Order.new(detail, supplier, quantity, price)
detail.orders << order
supplier.orders << order
detail.store()
supplier.store()
db.commit()
elsif cmd == ’4’
supplierName = input(’Supplier name prefix: ’)
suppliers = root.suppliers.find(supplierName, true,
supplierName + "\xFF", false)
if suppliers == nil
puts ’No such suppliers found’
else
for supplier in suppliers
puts supplier.name + "\t" + supplier.address
end
end
elsif cmd == ’5’
detailName = input(’Detail name prefix: ’)
details = root.details.find(detailName, true,
detailName + "\xFF", false)
if details == nil
puts(’No such details found’)
else
for d in details
puts d.name + "\t" + d.weight.to_s + "\t" + d.color
end
end
elsif cmd == ’6’
detailName = input(’Detail name: ’)
detail = root.details.get(detailName)
if detail == nil
puts ’No such detail’
else
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
for order in detail.orders
puts order.supplier.name
end
H
74
end
db.close()
puts ’End of session’
RU
BY
end
CO
AC
end
elsif cmd == ’7’
supplierName = input(’Supplier name: ’)
supplier = root.suppliers.get(supplierName)
if supplier == nil
puts ’No such supplier’
else
for order in supplier.orders
puts order.detail.name
end
end
elsif cmd == ’8’
break
else
puts ’Invalid command’
end
75
BY
CO
AC
H
3.9. DYBASE — OBJECT ORIENTED DBMS
Legende:
Script TestLink.rb →p. 71 in Eclipse Platform (version
2.1.1).
RU
Abbildung 3.7: Script TestLink.rb — DyBASE
BY
CO
AC
H
KAPITEL 3. SOFTWARE ENGINEERING TOOLS
RU
76
H
CO
Resources
AC
Anhang A
A.1 Web Sites
A.1.1 Ruby
Ruby homepage and downloads
Yukihiro Matsumoto: → http://www.ruby-lang.org/en/ (visited 28-Nov2003)
“Matz”
Ruby on Rails
→ http://www.rubyonrails.org (visited 22-Apr-2007)
BY
Programming Ruby — The Pragmatic Programmer’s Guide
→ file://localhost/C:/Programme/ruby/ProgrammingRuby.chm (visited 03-Dec-2003)
A.1.2 Java
RU
James Gosling / Bill Joy /Guy Steele /Gilad Bracha; The Java Language Specification,
Second Edition
→ http://java.sun.com/docs/books/jls/second edition/html/j.title.doc.html
(visited June 2002)
A.1.3 Updates to this Book
http://as.uni-lueneburg.de/ruby/updates.html (visited December 2003)
A.2 Glossary
JDT Java Development Tools
77
OODBMS Object Oriented Database Management System
PDE Plug-In Development Environment
RoR Ruby on Rails
AC
SWT Standard Widget Toolkit
UI User Interface
BY
CO
Bibliography
RU
A.3
H
ANHANG A. RESOURCES
78
H
AC
Literaturverzeichnis
[Arnold / Gosling, 1996] Ken Arnold / James Gosling; The Java Programming
Language (Addison-Wesley) 1996.
CO
[Bonin, 1991] Hinrich E. G. Bonin; Software-Konstruktion mit LISP, Berlin
New York (Walter de Gruyter), 1991. (german)
[Gamma / Beck, 2004] Erich Gamma / Kent Beck; Contributing to Eclipse —
Principles, Patterns, and Plug-Ins, Boston etc. (Addison-Wesley) 2004,
the eclipse series, series editors: Erich Gamma / Lee Nackman / John
Wiegand, ISBN 0-321-20575-8.
[Röhrl+, 2002] Armin Röhrl / Stefan Schmiedl / Clemens Wyss; Programmieren mit Ruby; eine praxisorientierte Einführung, Heidelberg
(dpunkt.verlag GmbH), 2002, ISBN 3-89864-151-1 (german).
BY
[Thomas / Hunt, 2002] David Thomas / Andrew Hunt; Programmieren
mit Ruby, deutsche Übersetzung von Reder Translations, München
u. a. (Addison-Wesley), 2002, ISBN 3-8273-1965-X (german).
[Wirdemann / Baustert] Wirdemann, R. / Baustert, T. ; Rapid Web Development mit uby on Rails, München, Wien (Hanser) 2006.
A.4 About this Document
The following software is used to produce this document:
Editor: GNU Emacs 21.3.1; JEdit 4.1 pre 5
RU
Layout: TeX, Version 3.14159 (Web2c 7.3.7x), LaTeX2e <2000/06/01>; Document Class: book 2001/04/21 v1.4e Standard LaTeX document class
Hardcopy: Corel CAPTURE 10; Corel PHOTO-PAINT 10 (version 10.427)
Figure: Microsoft Visio 2000 SR1 (6.0.2072)
Index: makeindex, version 2.13 [07-Mar-1997] (using kpathsea)
DVI→PS: LATEX-File (Device Independent) to Postscript: dvips(k) 5.90a Copyright
2002 Radical Eye Software (www.radicaleye.com)
79
PS→PDF: Postscript file to PDF-File: Adobe Acrobat Distiller 8.0
RU
BY
CO
AC
Security: Adobe Acrobat 8.0 Professional
H
LITERATURVERZEICHNIS
80
H
AC
Abbildungsverzeichnis
1.1
Contents of this book Ruby Coach . . . . . . . . . . . . . . . . . . .
2.1
2.2
2.3
2.4
Running HelloWorld.rb
Running quadric.rbw . .
Running biorhythm.rb .
Running excel.rbw . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
42
47
49
3.1
3.2
3.3
3.4
3.5
3.6
3.7
irb — Interactive Ruby Shell . . .
ruby-mode — Editor Emacs . . .
rd-mode — Editor Emacs . . . . .
ruby-plug-ins — Eclipse . . . . . . .
Script prime.rb — Eclipse . . . .
Script Hound.rd — rd2 . . . . .
Script TestLink.rb — DyBASE .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
52
53
54
58
59
64
75
.
.
.
.
.
.
.
.
RU
BY
CO
.
.
.
.
81
6
ABBILDUNGSVERZEICHNIS
RU
BY
CO
AC
H
82
H
AC
Tabellenverzeichnis
3.1
Eclipse — The Three Layers . . . . . . . . . . . . . . . . . . . . . .
RU
BY
CO
A.5 Index
83
57
BY
RU
H
AC
CO
Index
84
H
callcc, 34, 35
case, 17
CGI, 37
cgi.body, 37
cgi.br, 37
cgi.form, 37
cgi.h1, 37
cgi.head, 37
cgi.html, 37
cgi.out, 37
cgi.submit, 37
cgi.textarea(), 37
cgi.title, 37
class, 9, 18
clear(), 67
clone, 22, 31
close, 17
close(), 14, 68
Code
Notation, 7
Comment, 18
commit(), 68, 71
concat(), 31
Configuration, 56
Convention, 56
Corel
CAPTURE, 79
PHOTO-PAINT, 79
createBoolIndex(), 69
createIntIndex(), 69
createLongIndex(), 69
createRealIndex(), 69
createStrIndex(), 69
CO
’, 9, 15
::, 8
<, 18
<<, 15
<=>, 51
==, 51
==>, 8
=∼, 12
[], 51
#, 8
$, 11
$\, 11
‘, 16
AC
Index
BY
abs, 51
Acrobat, 80
Distiller, 80
Adobe
Acrobat, 80
Distiller, 80
Arithmeticoperations, 51
Arnold, Ken, 79
Array, 31
ascent, 67
attr accessor, 22
attr reader, 9
RU
Baustert, T., 79
Beck, Kent, 79
Bignum, 51
Bitoperations, 51
Bonin, Hinrich E. G., 79
Book
web-site, 77
Bracha, Gilad, 77
Date, 42
deallocate(), 66
call, 34, 35
85
AC
Gamma, Erich, 79
gc(), 70
get(), 15, 67
getRootObject(), 68, 71
gets, 9
getStorage(), 66
GL.ClearColor(), 38
GL.Enable(), 38
GL.Light(), 38
GL.LightModel(), 38
GL.Material(), 38
glut, 38
GNU
Emacs, 79
gohome, 46
Gosling, James, 77, 79
Hansson, David Heinemeier, 56
high, 67
highInclusive, 67
Hunt, Andrew, 79
id2name, 19
in, 15, 17
include, 26
Index, 66
Inheritance, 18
initialize, 9, 18
insert(), 67
inspect, 22
Integer, 51
InternetExplorer.Application,
46
irb, 13, 16
irb, 52
irb, 52
isLoaded(), 65
isModified(), 65
isPersistent(), 65
iterator(), 67
RU
BY
-e, 9
each, 29
each line, 12
each object(), 29
Eclipse, 56–57
example prime, 59
JFace, 57
Ruby plug ins, 58
Ruby Plug-In, 56
Runtime, 56
SWT, 57
three layers, 57
UI, 57
Workbench, 57
Workspace, 56
else, 17
Emacs
GNU, 79
ruby-mode, 53
empty?, 31
end, 9, 17, 18
eql?, 51
eruby, 55
excel.application, 48
exclusiveLock(), 66, 70
exit(), 42
typewriter-like, 7
for, 15, 17
Fulton, Hal, 9
CO
deallocateObject(), 68
def, 9, 18
Dir.open(.), 17
div, 51
divmod, 51
do, 14, 28
drop(), 67
dvips, 79
DyBASE, 63–74
example TestLink, 75
dybase.rb, 65
dybaseapi.dll, 65
dybasedll.dll, 65
File.open(), 28
find(), 67
Fixnum, 51
Font
H
INDEX
86
JDT, 57, 77
INDEX
LATEX, 79
load(), 65
loadObject(), 69
low, 67
lowInclusive, 67
puts, 9, 18
quo, 51
racc.bat, 60
Rails, 56
rd-mode, 54
rd2, 57–63
rd2.bat, 60
RDtool
example Hound, 64
Reflection, 56
remainder, 51
Remark, 18
remove(), 67
require, 15, 25, 26, 38
resetHash(), 69
return, 42
ri, 51
Röhrl, Armin, 79
rollback(), 68
RoR, 56, 78
Ruby
Eclipse, 56
Emacs, 53
eruby, 55
Help, 51
HTML, 55
Interactiv Shell, 52
ruby-mode, 53
Runtime
Eclipse, 56
AC
JEdit, 79
JFace
Eclipse, 57
join, 15
Joy, Bill, 77
H
87
BY
CO
makeObjectPeristent(), 68
Marshal.dump(), 28
Marshal.load(), 28
mathn, 38
Math::PI, 42
Matsumoto, Yukihiro, 21, 77
Matz, 9, 21, 77
message, 15
method missing(), 19
methods, 29
Microsoft
Visio, 79
Mixins, 25
modify(), 65
module, 24, 26
modulo, 51
Nackman, Lee, 79
net/http, 15
Net::HTTP.new(), 15
new, 9, 18
nowait, 70
RU
objectCacheSize, 68
ObjectSpace, 29
OODBMS, 65, 78
open(), 12, 14, 68
opengl, 38
pagePoolSize, 68
PDE, 57, 78
Persistent class, 65
print, 9, 11, 12, 14, 17
printf, 42
Schmiedl, Stefan, 79
Script
Biorhythm, 42
biorhythm, 47
Calling Future Code, 35
Continuation, 34
Directory Access, 17
Excel, 48
excel.rbw, 49
Factorial, 10
HelloWorld, 9
Inheritance, 18
to s, 51
AC
UI, 78
Eclipse, 57
unique, 69
unless, 34
unlock(), 66, 70
$USAGE, 42
usage(), 42
visible, 46
Visio
Microsoft, 79
CO
%w, 15
Web 2.0, 56
when, 17
while, 14
Wiegand, John, 79
win32ole, 46, 48
WIN32OLE.new(), 46, 48
WIN32OLE::VERSION, 46, 48
Wirdemann, R., 79
Workbench
Eclipse, 57
Workspace
Eclipse, 56
Wyss, Clemens, 79
RU
BY
Input-Output, 12
Internetexplorer, 46
Mixins, 25
MyCGI, 37
Namespace, 24
Prime Numbers, 11
Processes, 16
Quadric, 38
quadric, 42
Reflection, 29
RubyCoach, 6
Serialization, 27
Shallow copy, 22
Single Method, 19
TestLink, 71
Transaction, 13
turnround, 31
Web Pages, 15
Word Counter, 20
set(), 67
setGcThreashold(), 70
setRootObject(), 68, 71
sharedLock(), 66, 70
shift, 31, 34
size, 51
sort, 29
Source code
Notation, 7
STDERR, 42
$stdin, 9
Steele, Guy, 77
Storage, 68, 71
store(), 65
Struct.new(), 28, 29
super(), 18
SWT, 78
Eclipse, 57
system(), 16
TEX, 79
Thomas, Dave, 51
Thomas, David, 79
Thread.new(), 15
today, 42
to f, 51
H
INDEX
88
yield, 14
Yukihiro Matsumoto, 21, 77
INDEX
RU
BY
CO
AC
H
89