Ruby Basics: Difference between revisions
(3 intermediate revisions by the same user not shown) | |||
Line 16: | Line 16: | ||
</source> | </source> | ||
* The <code>require</code> statement reads and executes a file immediately, if it hasn't already. | * The <code>require</code> statement reads and executes a file immediately, if it hasn't already. | ||
* The <code>load</code> statement reads and executes the file, whether or not it has already done so. | |||
* Add this to the bottom of a Ruby file to run it directly (usually for debugging): | * Add this to the bottom of a Ruby file to run it directly (usually for debugging): | ||
<source lang="ruby"> | <source lang="ruby"> | ||
Line 34: | Line 35: | ||
* Hash | * Hash | ||
<source lang="ruby"> | <source lang="ruby"> | ||
to_s, to_i, to_a | to_s, to_i, to_a # convert to Strings, to Integer, to Array | ||
x.class | x.class # to see the class, returns Class object | ||
x.respond_to? 'values' # see if method x.values is defined | |||
</source> | </source> | ||
=== A word on booleans === | === A word on booleans === | ||
Line 59: | Line 61: | ||
== Operators == | == Operators == | ||
Ternary operator | === Ternary operator === | ||
<source lang="ruby"> | <source lang="ruby"> | ||
x = ( temp < 70 ) ? "cold" : "hot" | x = ( temp < 70 ) ? "cold" : "hot" | ||
</source> | </source> | ||
Spaceship operator | |||
=== Spaceship operator === | |||
<source lang="ruby"> | <source lang="ruby"> | ||
a<=>b | a<=>b | ||
Line 115: | Line 118: | ||
lang = :fr | lang = :fr | ||
dog = case lang | dog = case lang | ||
when :en | when :en then "dog" | ||
when :es | when :es then "perro" | ||
when :fr | when :fr then "chien" | ||
when :de | when :de then "Hund" | ||
else "dog" | else "dog" | ||
end | end | ||
Line 126: | Line 129: | ||
<source lang="ruby"> | <source lang="ruby"> | ||
case scale | case scale | ||
when 0 | when 0 then puts "lowest" | ||
when 1..3 | when 1..3 then puts "medium" | ||
when 4..5 | when 4..5 then puts "high" | ||
else puts "off scale" | else puts "off scale" | ||
end | end |
Latest revision as of 20:39, 18 June 2014
Program Structure
- one statement per line, or separate by semicolons
- wrap to next line with \
- end-of-line comment with #
- multi-line comment:
=begin
here is my comment
on two different lines
=end
- Hello World:
#!/usr/bin/ruby
puts 'Hello World'
- The
require
statement reads and executes a file immediately, if it hasn't already. - The
load
statement reads and executes the file, whether or not it has already done so. - Add this to the bottom of a Ruby file to run it directly (usually for debugging):
if $0 == __FILE__
my_test_method
end
Types
Everything inherits from the Object class and may access the methods of the Kernel module.
- nil is NilClass
- true is TrueClass, false is FalseClass
- Symbol (e.g. :dog)
- Fixnum includes Integer and Float
- Bignum is for arbitrarily large integers
- String
- Array
- Hash
to_s, to_i, to_a # convert to Strings, to Integer, to Array
x.class # to see the class, returns Class object
x.respond_to? 'values' # see if method x.values is defined
A word on booleans
Some may be used to thinking that a false value may be represented as a zero, a null string, a null character, or various other things. But in Ruby, all of these are true; in fact, everything is true except false
and nil
.
Variables
Foo # constant
foo # local variable
$foo # global variable
@foo # object/instance variable
@@foo # class variable
Parallel assignment:
x, y, z = 100, 200, 500
x = y = z = 0
Default-based assignment:
x ||= 10 # assigns 10 to x only if x hasn't yet been defined
Operators
Ternary operator
x = ( temp < 70 ) ? "cold" : "hot"
Spaceship operator
a<=>b
- if a < b it returns -1
- if a = b it returns 0
- if a > b it returns 1
Methods
def myMethod(a, b=default_value, c*) # define a method, a is a required argument
some code # b is optional
end # c represents an array of further arguments
myMethod(2, 3) # call the method
myMethod 2, 3 # call the method without parentheses
myObject.myMethod(a, b) # call an object method
myClass::myMethod(a, b) # call a class method
singleton methods are tied to an object, not the class:
str = "Hello, world!"
str2 = "Goodbye!"
def str.spell
self.split(/./).join("-")
end
str.spell # "H-e-l-l-o-,- -w-o-r-l-d-!"
str2.spell # error!
The return
at the end of a method can be omitted. A method always returns the last expression evaluated in its body, regardless of where that happens.
Control flow
if
(may optionally throw a then or colon after the condition):
if x < 10
puts "x < 10"
elsif x > 10
puts "x > 10"
else
puts "x is 10"
end
puts "hi there" if name == "Bill"
case
(a colon comes after each test case)
lang = :fr
dog = case lang
when :en then "dog"
when :es then "perro"
when :fr then "chien"
when :de then "Hund"
else "dog"
end
# "chien" is assigned to dog
case scale
when 0 then puts "lowest"
when 1..3 then puts "medium"
when 4..5 then puts "high"
else puts "off scale"
end
# => high
while
(may optionally throw in a do after the condition)
while i < breeds.size
temp << breeds[i].capitalize
i +=1
end
begin
puts temp
temp += 0.1
end while temp < 98.6
unless
is the opposite of if
, until
is the opposite of while
loop with break
:
loop do
print "Type something: "
line = gets
break if line =~ /q|Q/
puts line
end
for
loop and variants:
for i in 1..5
print i, " "
end
for i in 1..5 do print i, " "
5.times { |i| print i, " " }
1.upto(5) { |i| print i, " " }
5.downto(1) { |i| print i, " " }
end a program early:
exit if str.nil? or str.empty?
abort "#{temp} is not a valid number." if temp !~ /-?\d+/
Code Blocks and Iteration
each
, select
, and detect
accept code blocks
single-line form:
[1,2,3].each { |i| puts i}
multi-line form:
[1,2,3].each do |i|
puts i
end
can also do python-style:
for i in [1,2,3]
puts i
end
each_index
to access index of list elements:
list.each_index do |i|
puts "#{i} -> #{list[i]}"
end
code blocks as objects:
log = lambda { |msg| puts "[LOG] #{msg}" }
log.call("A test log message.")
log.class # Proc
call a code block from a function (the block needs to be the last argument):
def log(name, message, &level)
print "log file %s: " % name
level.call(message) if level
end
error = lambda { |msg| puts "[ERROR] #{msg}" }
log("test.log", "Here is an error message", &error)
log("test.log", "Here is a warning message") {|msg| puts "[WARN] #{msg}"}
access external variables from a code block:
tax_percent = 6
position = lambda do
"I have always supported a #{tax_percent}% tax on imported limes."
end
puts position.call
# => "I have always supported a 6% tax on imported limes."
tax_percent = 7.25
puts position.call
# => "I have always supported a 7.25% tax on imported limes."
build a custom iterator (yield calls the anonymous code block argument):
class Tree
attr_reader :value
def initialize(value)
@value = value
@children = []
end
def <<(value)
subtree = Tree.new(value)
@children << subtree
return subtree
end
def each
yield value
@children.each do |child|
child.each { |e| yield e }
end
end
end
t = Tree.new("Parent")
child1 = t << "Child 1"
child1 << "Grandchild 1.1"
child1 << "Grandchild 1.2"
child2 = t << "Child 2"
child2 << "Grandchild 2.1"
t.each { |x| puts x }
# Parent
# Child 1
# Grandchild 1.1
# Grandchild 1.2
# Child 2
# Grandchild 2.1
Error Handling
begin
Article.find(1037)
rescue ActiveRecord::RecordNotFound
puts "We couldn't find that record"
end
begin
x = Math.sqrt(y/z)
# ...
rescue => err
puts err
end
begin
# Error-prone code...
rescue
# Handle exceptions
ensure
# This code is always executed
end
Runtime Evaluation
def calculate(op1, operator, op2)
string = op1.to_s + operator + op2.to_s
# operator is assumed to be a string; make one big
# string of it and the two operands
eval(string) # Evaluate and return a value
end
@alpha = 25
@beta = 12
puts calculate(2, "+", 2) # Prints 4
puts calculate(5, "*", "@alpha") # Prints 125
puts calculate("@beta", "**", 3) # Prints 1728
puts "Method name: "
meth_name = gets
puts "Line of code: "
code = gets
string = %[def #{meth_name}\n #{code}\n end] # Build a string
eval(string) # Define the method
eval(meth_name) # Call the method
if platform == Windows
def my_action
action1
end
elsif platform == Linux
def my_action
action2
end
else
def my_action
default_action
end
end