Caution: there may be errors.
---------------------------------------------
stuff after => is return value
(e.g., printed by interactive interpreter irb)
#!/usr/bin/ruby # begins file
# begins comment
=begin
these lines are
ignored by interpreter
=end
__END__
all subsequent lines ignored
---------------------------------------------
"then" is not required except in expression-type "if":
x = if a>0 then b else c end
---------------------------------------------
"do" is required for "loop", and must be
on same line as loop -- "loop do"
"do" is required for iterators like
list.each do |x|
print "#{x} "
end
list.each_index do |x|
print "#{list[x]} "
end
n=list.size
n.times do |i|
print "#{list[i]} "
end
n=list.size-1
0.upto(n) do |i|
print "#{list[i]} "
end
"do" is not required for "while" or "until"
---------------------------------------------
When in doubt, try it out.
The interpreter is always right.
If you can think it, it's already in Ruby.
-- msb
---------------------------------------------
if expr
elsif expr
else
end
---------------------------------------------
while expr
...
end
---------------------------------------------
until expr
...
end
---------------------------------------------
loop do # loops forever, "do" is required
...
end
---------------------------------------------
for var in list
...
end
list can be a range of integers
n=list.size-1
for
i in 0..n do
print "#{list[i]} "
end
---------------------------------------------
break -- breaks out of loop
next -- immediately goes to next iteration (e.g., continue)
retry -- restart entire loop, including condition or list
Only for "for" or iterator, not "while" or "until".
redo -- redoes current cycle of loop without reevaluating
condition or getting next item
The redo keyword is the generalized form of retry for loops.
It works for while and until loops just as retry works for
iterators. -- The Ruby Way Seems to contradict previous def.
---------------------------------------------
case "This is a character string."
when "some value"
puts "Branch 1"
when "some other value"
puts "Branch 2"
when /char/
puts "Branch 3"
else
puts "Branch 4"
end
prints "Branch 3"
---------------------------------------------
method (function) definition
one arg with default value
puts (string out) call with method string arg inserted
and capitalized by calling string method
def h(name = "World")
puts "Hello #{name.capitalize}!"
end
in call of method, parens around args are optional
unless req'd to avoid confusion
---------------------------------------------
class definition
@xxx is an instance variable
class Greeter
def initialize(name = "World")
@name = name
end
def say_hi
puts "Hi #{@name}!"
end
def say_bye
puts "Bye #{@name}, come back soon."
end
end
---------------------------------------------
object creation and call
g = Greeter.new("Pat")
g.say_hi
Hi Pat!
g.say_bye
Bye Pat, come back soon.
---------------------------------------------
get methods that object responds to
Greeter.instance_methods
=> ["method", "send", "object_id", "singleton_methods",
"__send__", "equal?", "taint", "frozen?",
"instance_variable_get", "kind_of?", "to_a",
"instance_eval", "type", "protected_methods", "extend",
"eql?", "display", "instance_variable_set", "hash",
"is_a?", "to_s", "class", "tainted?", "private_methods",
"untaint", "say_hi", "id", "inspect", "==", "===",
"clone", "public_methods", "respond_to?", "freeze",
"say_bye", "__id__", "=~", "methods", "nil?", "dup",
"instance_variables", "instance_of?"]
get methods defined specifically for object
Greeter.instance_methods(false)
=> ["say_bye", "say_hi"]
---------------------------------------------
test which methods object responds to
g.respond_to?("name")
=> false
g.respond_to?("say_hi")
=> true
g.respond_to?("to_s")
=> true
---------------------------------------------
to view or change instance variables
class Greeter
attr_accessor :name
end
you can open a class up again and modify it.
The changes will be present in any new objects you create
and available in existing objects of that class.
g = Greeter.new("Andy")
g.respond_to?("name")
=> true
g.respond_to?("name=")
=> true
g.say_hi
Hi Andy!
g.name="Betty"
=> "Betty"
g.name
=> "Betty"
g.say_hi
Hi Betty!
Using attr_accessor defined two new methods --
name to get the value, and name= to set it.
---------------------------------------------
test if variable is nil
if @names.nil?
...
---------------------------------------------
test if variable is a list
if @names.respond_to?("each")
# @names is a list of some kind, iterate!
---------------------------------------------
iterate over list using "each"
@names.each do |name|
puts "Hello #{name}!"
end
---------------------------------------------
find which methods anything responds to --
119 of them for a list!
names = ["Albert", "Brenda", "Charles", "Dave", "Englebert"]
puts(names.methods)
---------------------------------------------
use "join" to print list with designated separator string
puts "Goodbye #{@names.join(", ")}. Come back soon!"
---------------------------------------------
execute block of code only if file name is same as file name called
to execute program (i.e., if file is "main"). The rest of the code
in the file can be, e.g., method or class definitions, which can be
used as a library even if the file is not "main".
if __FILE__ == $0
...
---------------------------------------------
execute system command(s)
`date` = string output of cmd
%x{ls -alF} = string output of cmd
To put value of variable into cmd string, have to use #{}:
x = "poo"
s = %x{echo #{x}}.chomp
print("*", s, "*", "\n")
prints *poo*
To print to the screen via echo have to explictly redirect to /dev/tty:
%x{echo #{chnum} #{chname} #{day} #{date} #{time} #{ampm} > /dev/tty }
but then the %x{} thing itself returns an empty string.
This prints to tty and returns the full string that was printed:
s = %x{echo #{chnum} #{chname} #{day} #{date} #{time} #{ampm} | tee /dev/tty }.chomp
$?.exitstatus is cmd exit code; $? also contains other info
---------------------------------------------
find the type of an object
n.class
---------------------------------------------
read a file
file = File.open("testfile, "r")
File.open("testfile") do |file|
file.each_line {|line| puts "Got #{line.dump}" }
end
File.open("mary") do |file|
file.each_line { |line|
puts("Got #{line.dump}")
}
end
File.open("mary") do |file|
file.each_line do |line|
puts("Got #{line.dump}")
end
end
File.open("mary") do |file|
file.each_line do |line|
puts("Got #{line}")
end
end
File.open("mary") do |file|
n = 1
file.each_line do |line|
puts("#{n} #{line}")
n = n + 1
end
end
---------------------------------------------
write a file (with each line = the line of the input file reversed)
File.open($*[0], "r") do |file|
File.open("goo", "w") do |outfile|
n = 1
file.each_line do |line|
puts("#{n} #{line.chomp!.reverse!}")
outfile.puts("#{n} #{line}")
n = n + 1
end
end
end
# do it the old way -- one nested level instead of three
infile = File.open($*[0], "r")
outfile = File.open("hoo", "w")
n = 1
while line = infile.gets
puts("#{n} #{line.chomp!.reverse!}")
outfile.puts("#{n} #{line}")
n = n + 1
end
infile.close
outfile.close
---------------------------------------------
cmd-line args
$* is an array of strings, each a cmd-line arg
$*[0] is the first arg
$0 is the name of the main ruby file executed
output each line (numbered) of file named in cmd line
File.open($*[0]) do |file|
n = 1
file.each_line do |line|
puts("#{n} #{line}")
n = n + 1
end
end
---------------------------------------------
strings, substrings
"mark"[1,3] = "ark"
"mark"[1,1] = "a"
"mark"[1] = 97
"mark"[1..3] = "ark"
---------------------------------------------
char replacement/deletion within strings
str.sub(pattern, replacement)
replaces first occurrence of pattern in str by replacement
pattern can be a regexp -- /.../
for deletion, use '' for replacement
gsub replaces all occurrences
sub!, gsub! changes original string
---------------------------------------------
scanf -- dissect string into numeric or string components
and load them into variables
require "scanf"
field1, field2, ... = str.scanf(formatString)
---------------------------------------------
splitting a string (may be a multi-line list)
into an array of strings, at delimiter(s)
`ls -alF`.split("\n")[34]
---------------------------------------------
convert integer to byte in string
# make ch a one-byte string,
# set it's byte to ascii code of A, B, ...
# print it as a string
time_ar.each_index do |i|
ch = "x"; ch[0] = i + 65
print(ch, ' ', time_ar[i], "\n")
end
---------------------------------------------
Remove first element of an array!
x="ABCDE"
x=x[1..(x.size - 1)]
puts(x)
puts(x[0..0])
prints
BCDE
B
x=x[1..999] also works
---------------------------------------------