ruby: from zero to hero

Download Ruby: from zero to hero

If you can't read please download the document

Upload: diego-lemos

Post on 15-Apr-2017

2.286 views

Category:

Software


4 download

TRANSCRIPT

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