Download - Ruby: from zero to hero
Ruby: from ZERO to HERODiego LEMOS@dlresende
BeginningCreated by Yukihiro Matsumoto, known as Matz, in the mid-1990s in Japan.
The Ruby LanguageRuby is a dynamic programming language with a complex but expressive grammar and a core class library with a rich and powerful API. Ruby draws inspiration from Lisp, Smalltalk, and Perl, but uses a grammar that is easy for C and Java programmers to learn. Ruby is a pure object-oriented language, but it is also suitable for procedural and functional programming styles. It includes powerful metaprogramming capabilities and can be used to create domain-specific languages or DSLs.
The Ruby PhilosophyRuby is designed to make programmers happy.
Is there a Ruby IDE?
Source: http://www.sitepoint.com/ides-rubyists-use/
Source: http://www.sitepoint.com/editor-rubyists-use/
Interpreter% ruby -e 'puts "hello world!"'hello world!
% ruby hello.rbhello world!
3 toolsirb
ri
gem
Interactive Ruby with irb$ irb>> "Ruby! " * 3=> "Ruby! Ruby! Ruby! ">> quit$
Ruby Documentation with riri Arrayri Array.sortri Hash#eachri Math::sqrt
Package Management with gem# gem install railsSuccessfully installed activesupport-1.4.4Successfully installed activerecord-1.15.5Successfully installed actionpack-1.13.5Successfully installed actionmailer-1.3.5Successfully installed actionwebservice-1.2.5Successfully installed rails-1.2.56 gems installedInstalling ri documentation for activesupport-1.4.4...Installing ri documentation for activerecord-1.15.5......etc...
Rake# Rake is a software task management and build automation # tool
task :default => [:test]
task :test do ruby "test/tc_simple_number.rb"end
app/ Bin/# Files for command-line execution lib/appname.rb# Classes and so onlolcatz/moar.rb# lolcatz::moar Rakefile# Tasks like testing, building Gemfile# Defines the source of the gem README test,spec,features/# Whichever means of testing you go for appname.gemspec# If it's a gem
Project Structure
Comments# Comment line with #
=beginComment multiple lines...like thisNot very popular=end
Arithmetic operators10 + 1 #=> 11 # addiction11 - 1 #=> 10 # subtraction10 * 2 #=> 20 # multiplication30 / 3 #=> 10 # division2 ** 5 #=> 32 # exponent17 % 3 #=> 2 # modulus
Comparison operators1 == 1 #=> true # equality8 != 1 #=> true # inequality10 < 2 #=> false # less than35 > 5 #=> true # greater than1 true # less than or equal to5 >= 5 #=> true # greater than or equal to
Combined comparison operator (1/2)1 10# => -110 1# => 11 1# => 0
Combined comparison operator (2/2)# === (case equality)
# For class Object, effectively the same as calling #==,# but typically overridden by descendants to provide meaningful# semantics in case statements.
case some_objectwhen /a regex/ # The regex matcheswhen 2..4 # some_object is in the range 2..4when lambda {|x| some_crazy_custom_predicate } # the lambda returned trueend
Regexp and Range# Regular Expressions and Ranges have a literal syntax in Ruby:
/[Rr]uby/ # Matches "Ruby" or "ruby"/\d{5}/ # Matches 5 consecutive digits1..3 # All x where 1 49 (0011 0001)# XOR~a # => -61 (1100 0011)# One Complementa 240 (1111 0000)# Left Shifta >> 2# => 15 (0000 1111)# Right Shift
Everything is Object# Numeric literals are objects3.class# => Fixnum3.to_s # => "3"
# Arithmetic is just syntactic sugar# for calling a method on an object1.+(3) # => 410.* 5 # => 50
Special Values are Objectsnil # equivalent to null in other languagestruefalse
nil.class# => NilClasstrue.class# => TrueClassfalse.class# => FalseClass
Logical Operators (1/2)!true #=> false# Nottrue && true #=> true # ANDtrue || false #=> true # ORnot true #=> false # Nottrue and true #=> true # Andtrue or 0 #=> true # Or
# and is the same as && but with lower precedence# they both use short-circuit evaluation (same for or)
Logical Operators (2/2)# and, or operators are meant to be used as flow-control # constructs to chain statements together until one of them # returns true or false.
# do_something_else only called if do_something succeeds. do_something() and do_something_else()
# log_error only called if do_something fails. do_something() or log_error()
Strings# Strings are objects
'I am a string'.class # => String "I am a string too".class # => String
# Prefer single quoted strings to double quoted ones where# possible# Double quoted strings perform additional inner calculations
String Interpolationplaceholder = 'use string interpolation'"I can #{placeholder} when using double quoted strings" # => "I can use string interpolation when using double quoted strings"
Combine strings# but not with numbers 'hello ' + 'world' # => "hello world" 'hello ' + 3 # => TypeError: can't convert Fixnum into String 'hello ' + 3.to_s # => "hello 3"
# combine strings and operators 'hello ' * 3 # => "hello hello hello "
# append to string 'hello' "hello world"
Print to the output# print to the output with a newline at the end puts "I'm printing!"# => I'm printing!# => nil
# print to the output without a newline print "I'm printing!" # => I'm printing! => nil
Assignments (1/3)x = 25 # => 25x # => 25
# Note that assignment returns the value assigned# This means you can do multiple assignment:
x = y = 10 # => 10x # => 10y # => 10
# By convention, use snake_case for variable namessnake_case = true
Assignments (2/3)# Assignment can be combined with operators such as + and - :
x += 1# Increment x: note Ruby does not have ++.y -= 1# Decrement y: no -- operator, either.
Assignments (3/3)# Ruby supports parallel assignment, allowing more than one value # and more than one variable in assignment expressions:
x, y = 1, 2 # Same as x = 1; y = 2a, b = b, a # Swap the value of two variablesx,y,z = [1,2,3] # Array elements automatically assigned to variables
Symbols# Symbols are objects.# Symbols are immutable, reusable constants represented# internally by an integer value. # They're often used instead of strings to efficiently convey# specific, meaningful values.
:pending.class # => Symbolstatus = :pendingstatus == :pending # => truestatus == 'pending' # => falsestatus == :approved # => false
Arrays (1/4)# This is an arrayarray = [1, 2, 3, 4, 5] # => [1, 2, 3, 4, 5]
# Arrays can contain items of different types[1, 'hello', false] # => [1, "hello", false]
Arrays (2/4)# Arrays can be indexed# ...from the frontarray[0] # => 1array.first # => 1array[12] # => nil
# ...from the endarray[-1] # => 5array.last # => 5
# ...with a start index and lengtharray[2, 3] # => [3, 4, 5]
# ...or with a rangearray[1..3] # => [2, 3, 4]
Arrays (3/4)
# Like arithmetic, [var] access# is just syntactic sugar# for calling a method [] on an objectarray.[](0) # => 1array.[] 0 # => 1array.[] 12 # => nil
# In Ruby, parentheses are usually optional and they are # commonly omitted, especially when the method being invoked # takes no arguments.
Arrays (4/4)# Reverse an Arraya = [1, 2, 3]a.reverse! # => [3, 2, 1]
# Add to an array like thisarray [1, 2, 3, 4, 5, 6]# Or like thisarray.push(6) # => [1, 2, 3, 4, 5, 6]
# Check if an item exists in the arrayarray.include?(1) # => true
Exclamation and question marksarray = [1, 2, 3]
# The question mark is a code style convention;# it indicates that a method returns a boolean value.# The question mark is a valid character at the end of a method.# These methods are called predicated methods.array.include?(1) # => true
# In general, methods that end in ! indicate that the method will# modify the object it's called on. Ruby calls these "dangerous# methods" because they change state that someone else might # have a reference to.# These methods are called mutator methods.array.reverse! # => [3, 2, 1]
array # => [3, 2, 1]
Hashes (1/2)# Hashes are Ruby's primary dictionary with keys/value pairs.# Hashes are denoted with curly braces:hash = { 'color' => 'green', 'number' => 5 }
hash.keys # => ['color', 'number']
# Hashes can be quickly looked up by key:hash['color'] # => 'green'hash['number'] # => 5
# Asking a hash for a key that doesn't exist returns nil:hash['nothing here'] # => nil
# Since Ruby 1.9, there's a special syntax when using symbols as# keys.# Hashes can use any object as a key, but Symbol objects are the # most commonly used. Symbols are immutable, interned strings.new_hash = { defcon: 3, action: true }
new_hash.keys # => [:defcon, :action]new_hash.values # => [3, true]
# Check the existence of keys and values in hashnew_hash.key?(:defcon) # => truenew_hash.value?(3) # => true
# Tip: Both Arrays and Hashes are Enumerable# They share a lot of useful methods such as each, map, count,# and moreHashes (2/2)
# Code blocks are chunks of code that you can associate with# method invocations. Its analogous to lambdas, # anonymous functions or closures in other languages.
# We can define blocks between braces...some_method { puts 'hello' }
# ...or between do..endsome_method do print 'hello ' print 'world'end
# The Ruby standard is to use braces {} for single-line blocks and # do..end for multi-line blocks.Blocks (1/2)
# The keyword yield executes the block passed to the methoddef some_method yield('hello', 'world')end
# You can pass parameters to blocks like this:some_method { |str1, str2| puts str1 + ' ' + str2 }
# The ability to associate a block of code with a method invocation # is a fundamental and very powerful feature of Ruby.Blocks (2/2)
# Control structures such as if that would be called# statements in other languages are actually expressions
if true 'if'elsif false 'else if, optional'else 'else, optional'end
# => "if"Control Structures (1/7)
for counter in 1..5 puts "iteration #{counter}"end
# => iteration 1# => iteration 2# => iteration 3# => iteration 4# => iteration 5Control Structures (2/7)
# HOWEVER, No-one uses for loops.# Instead you should use the "each" method and pass it a block.
# The "each" method of a range runs the block once for each # element of the range.# The block is passed a counter as a parameter.
# Calling the "each" method with a block looks like this:(1..5).each { |counter| puts "iteration #{counter}" }
# => iteration 1# => iteration 2# => iteration 3# => iteration 4# => iteration 5Control Structures (3/7)
# If you still need an index you can use "each_with_index"# and define an index variablearray.each_with_index do |element, index| puts "#{element} is number #{index} in the array"endControl Structures (4/7)
counter = 1while counter iteration 1# => iteration 2# => iteration 3# => iteration 4# => iteration 5
# although the language does support while loops, it is more# common to perform loops with iterator methods:
3.times { print "Ruby! " } # Prints "Ruby! Ruby! Ruby! "Control Structures (5/7)
letter = 'B'
case letter when 'A' puts 'a' when 'B' puts 'b' when 'C' puts 'c' else puts 'none of the above'end
#=> "b"Control Structures (6/7)
# cases can also use rangesgrade = 82case grade when 90..100 puts 'Hooray!' when 80...90 puts 'OK job' else puts 'You failed!'end
#=> "OK job"Control Structures (7/7)
begin # code here that might raise an exception raise NoMemoryError, 'You ran out of memory.'rescue NoMemoryError => exception_variable puts 'NoMemoryError was raised', exception_variablerescue RuntimeError => other_exception_variable puts 'RuntimeError was raised now'else puts 'This runs if no exceptions were thrown at all'ensure puts 'This code always runs no matter what'end
Exception handling
# Methods (and all blocks) implicitly return the value of the last # statementdef sum(x, y) x + yend
# Parentheses are optional where the result is unambiguous# Method arguments are separated by a commasum 3, 4 #=> 7
sum sum(3, 4), 5 #=> 12Methods (1/10)
def sum_if_positive(x, y) return 0 if x + y < 0 # Note if used as a statement modifier x + yendMethods (2/10)
# Define another name for the same method.# It is common for methods to have multiple names in Rubyalias size length # size is now a synonym for lengthMethods (3/10)
# All methods have an implicit, optional block parameter# that can be invoked with the yield keyword
def surround print '{' yield print '}'endsurround { print 'hello'}
# => {hello}Methods (4/10)
# You can pass a block to a function# "&" marks a reference to a passed block
def guests(&block) block.call 'some_argument' endguests { |input| print input}
#=> some_argumentMethods (5/10)
# If you pass a list of arguments, it will be converted to an array# That's what splat operator ("*") is for
def list(*array) array.each { |elem| print elem }endlist(1, 2, 3)
#=> 123Methods (6/10)
# If a method returns an array, you can use destructuring # assignment
def foods ['pancake', 'sandwich', 'quesadilla']end
breakfast, lunch, dinner = foodsbreakfast #=> 'pancake'dinner #=> 'quesadilla'lunch #=> 'sandwich'Methods (7/10)
def global_quare(x) x*xend
# When a method is defined outside of a class or a module, it is effectively a global function rather than a method to be invoked on an object. (Technically, however, a method like this becomes a private method of the Object class.)
Methods (8/10)
# Methods can also be defined on individual objects by prefixing # the name of the method with the object on which it is defined. # Methods like these are known as singleton methods, and they # are how Ruby defines class methods:
def Math.square(x) x*x end
# Define a class method of the Math module# The Math module is part of the core Ruby library, and this code adds a new method to it. This is a key feature of Rubyclasses and modules are open and can be modified and extended at runtime.
Methods (9/10)
# Methods that end with an equals sign = are special because # Ruby allows them to be invoked using assignment syntax.# If an object o has a method named x= , then the following two # lines of code do the very same thing:
o.x=(1)# Normal method invocation syntaxo.x = 1# Method invocation through assignmentMethods (10/10)
# A class is a collection of related methods that operate on the state of an object
class Human # A class variable is shared by all instances of this class. @@species = 'H. sapiens'
def initialize(name, age = 0) # Basic initializer # Assign the argument to the "name" instance variable for the instance @name = name # If no age given, we will fall back to the default in the arguments list. @age = age end
def name=(name) # Basic setter method @name = name end
def name # Basic getter method @name endendClasses (1/5)
class Human
@@species = 'H. sapiens'
# A class method uses self to distinguish from instance methods. # It can only be called on the class, not an instance. def self.say(msg) puts msg end
# Instance method def species @@species endendClasses (2/5)
# Instantiate a classdiego = Human.new('Diego Lemos')
# Calling methodsdiego.species #=> "H. sapiens"diego.name #=> "Diego Lemos"diego.name = 'Diego LEMOS' #=> "Diego LEMOS"diego.name #=> "Diego LEMOS"
# Calling the class methodHuman.say('hello') #=> "hello"Classes (3/5)
class Person # Getter/setter methods can also be created individually like this: attr_reader :name attr_writer :nameend
person = Person.newperson.name = 'Diego'person.name # => "Diego"Classes (4/5)
class Person # Even this can get repetitive. # When you want both reader and writer just use accessor! attr_accessor :nameend
person = Person.newperson.name = 'Diego'person.name # => "Diego"Classes (5/5)
# Variables that start with $ have global scope$var = 'global variable'defined? $var #=> "global-variable"
# Variables that start with @ have instance scope@var = 'instance variable'defined? @var #=> "instance-variable"
# Variables that start with @@ have class scope@@var = 'class var'defined? @@var #=> "class variable"
# Variables that start with a capital letter are constantsVar = 'constant'defined? Var #=> "constant"Variables scope
class Human # Class variable is shared among the class and all of its descendants @@foo = 0
def self.foo @@foo end
def self.foo=(value) @@foo = value endend
class Worker < Humanend
Human.foo #=> 0Worker.foo #=> 0
Human.foo = 2 #=> 2Worker.foo #=> 2Derived classes (1/2)
class Human # Class instance variable is not shared by the class's descendants @bar = 0
def self.bar @bar end
def self.bar=(value) @bar = value endend
class Doctor < Humanend
Human.bar # => 0Doctor.bar # => nilDerived classes (2/2)
module ModuleExample def foo 'foo' endend
# Including modules binds their methods to the class instancesclass Person include ModuleExampleend
Person.foo # => NoMethodError: undefined method `foo' for Person:ClassPerson.new.foo # => 'foo'
# Extending modules binds their methods to the class itselfclass Book extend ModuleExampleend
Book.foo # => 'foo'Book.new.foo # => NoMethodError: undefined method `foo'Modules
# Ruby provides a framework in its standard library for setting up, # organizing, and running tests called Test::Unit.
require_relative "../lib/simple_number"require "test/unit"
class TestSimpleNumber < Test::Unit::TestCase
def test_simple assert_equal(4, SimpleNumber.new(2).add(2) ) assert_equal(6, SimpleNumber.new(2).multiply(3) )end
endTest::Unit
Go further (1/2)
Go further (2/2)
Referenceshttp://stackoverflow.com/questions/5616912/ruby-triple-equal#5617086
https://learnxinyminutes.com/docs/ruby/
http://www.sitepoint.com/ides-rubyists-use/
http://stackoverflow.com/questions/1426826/difference-between-and-and-in-ruby
http://stackoverflow.com/questions/1345843/what-does-the-question-mark-operator-mean-in-ruby
http://rubylearning.com/satishtalim/ruby_blocks.html
http://www.tutorialspoint.com/ruby/ruby_operators.htm
https://github.com/blog/2047-language-trends-on-github
http://stackoverflow.com/questions/2191632/begin-rescue-and-ensure-in-ruby
http://stackoverflow.com/questions/4370960/what-is-attr-accessor-in-ruby
https://www.ruby-lang.org/en/documentation/
http://stackoverflow.com/questions/614309/ideal-ruby-project-structure
http://rake.rubyforge.org/
https://en.wikibooks.org/wiki/Ruby_Programming/Unit_testing
http://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and