Skip to content

Lecture 01

autumncollection edited this page Feb 2, 2016 · 4 revisions

About Ruby

  • http://www.ruby-lang.org
  • Made in Japan (*1995) by Yukihiro “matz” Matsumoto
  • Combining Perl, Smalltalk, Ada, Lisp and other
  • Multipurpose language (not only for web sites)
  • Dynamic-typing
  • Meta-programming
  • There are many alternative implementation such as JRuby, Rubinius, IronRuby or MagLev

Natural, but not simple

  • Closer to natural language
1000.times { puts "I will never write unreadable code" }
  • Clear syntax:
    • semicolons, brackets - optional
  • More ways to do one thing
    • depends on the context and conventions, what to use

Language basics

Naming conventions

  • methods, variables, files
    • snakes_style
  • classes and modules
    • CamelCaseStyle
  • constants
    • UPPER_CASE_SNAKES

If-then-else

  • the classic form
if you.like? Ruby
  you.use! Ruby
else
  you.use! Anything
end
  • the modifier form
you.use! Ruby if you.like? Ruby
  • the negative form
you.use! Anything unless you.like? Ruby

# Do not use this!
you.use! Anything if !you.like? Ruby

Cycles

  • while / until / loop
while input = STDIN.gets.chomp and !input.empty?
  puts input.reverse
end

puts "I was in #{ cities.pop }" until cities.empty?
  • for
    • strongly recommended to avoid - there are other ways
args = [1, 2, 3, 4]
loop do
  break if args.empty?
  value = args.shift
end
  • Enumerable methods - read further
cities.each { |city| puts "I was in #{ city }" }

Switch

  • I. way
case input
  when "help", "?"
    puts "type help, a number or introduce yourself "
  when Integer
    input.times { puts "Hello" }
  when /^My name is (.*)$/
    puts "Hello #{ $1 }"
  else
    puts "I don't understand"
end
  • II. way
case
  when input.size < 8 then "What a short name"
  when input.size < 15 then "That's OK :)"
  else "That long? Seriously?"
end

Symbols

  • almost, but not quite, entirely unlike strings
  • :name vs. "name"
    • :name is immutable
    • :name is in memory only once
  • useful / recommended as hash (Ruby's dictionary / associative array) keys - read further
  • never do this with user generated data
"name".to_sym # => :name 

Boolean expressions

  • not-true - only false or nil

  • true - everything else (true, '', 0, [], ...)

  • &&, || - recommended for Boolean operations in conditions (higher priority)

puts "Secure password" if p.size > 300 && p !~ /^[a-z]*$/

Object-oriented programming

Methods

  • definitions

    • basic
# with () most of the time
def say_hello(name)
  "Hello #{ name }"
end
  • no arguments
# we don't use ()
def say_hello
  "Hello #{ name }"
end
  • optional arguments
def say_hello(name = "Johny")
  "Hello #{ name }"
end
  • undefined count of arguments
def say_hello(greeting, *names)
  "#{ greeting } #{ names.join(", ") }"
end
  • arguments given as options (hash)
def say_hello(options = {})
  options = {:greeting => "Hello", :name => "World"}.merge(options)
  "#{ options[:greeting] } #{ options[:name] }"
end
  • class methods
def self.say_hello(name)
  # ...
end

# or

# This is very useful when you have many class methods
class << self
  def say_hello(name)
    # ...
  end
end
  • calls
say_hello
say_hello(World)

names = ["Sisoj", "Psojic"]
say_hello(*names)

say_hello(:greeting => "Hello", :name => "World")
say_hello(greeting: "Hello", name: "World")       # Ruby 1.9 syntax

Classes

  • definitions
class Phone
  attr_accessor :name
  attr_reader :number

  def initialize(name, number)
    @name, @number = name, number
  end
end

class Window include Draggable

attr_accessor :position_x, :position_y end

class Icon include Draggable

attr_accessor :position_x, :position_y end


 * usable mixins: `Enumerable`, `Sortable`

#### Strings & Regexp
* I. way

```ruby
user_name = "Ivan"
  • II. way
subject = %{Hello "#{ user_name }"}

# or

subject = %|Hello "#{ user_name }"|
  • III. way
message = <<EOS
            "#{ subject }"
            Thanks for using Ruby
EOS
message = <<-EOS
             "#{ subject }"
             Thanks for using Ruby
             EOS

Useful String methods

  • chomp
"123\n".chomp # => "123"
  • strip
"  123  ".strip # => "123"
  • include?
"12345".include? "234" # => true
  • upcase, downcase, start_with?, end_with?
"hello".upcase # => "HELLO"

Regexps

  • definition
/^hello$/
Regexp.new("^hello$")
  • usage
# the most easy way
"Please call 123456"[/[0-9]+/]

# captured
"Please call 123456"[/([0-9]+)/, 1]
"Please call some number"[/([0-9]+)/, 1] # nil

# quick match
"hello" =~ /^hello$/ ? 'yes' : 'no' # yes
# use \A \z -> String endigns againts ^$ => start/end of line
"hello" =~ /\Aahoj\z/ # nil

# complicated captured
"Chuck Norris".match(/([a-z]+) ([a-z]+)/i)
Regexp.last_match(1) # Chuck
Regexp.last_match(2) # Norris

match = "Chuck Norris used Roundhouse Kick".match(/^(.*) used (.*)$/)

puts "#{ match[2] } has killed again"
puts "No surprise" if match[1] =~ /Chuck/

# use in strings for split / sub
"<title>Ruby</title><p>lang</p>".split(/<\/?.*?>/)
# => ["", "Ruby", "", "Lang"]

"<title>Ruby</title><p>lang</p>".split(/(<\/?.*?>)/)
# => ["", "<title>", "Ruby", "</title>", "", "<p>", "lang", "</p>"]

Collections & Blocks

Blocks

open("message.txt") { |file| puts file.read }


#### Collections
* arrays

```ruby
cities = ["brno", "praha"]
# same as
cities = %w(brno praha)
# add element to array
cities << 'ostrava'
# add more elements to array
cities.push('olomouc', 'postoloprty')
```

** map
```ruby
# cities with upper cased first letter
cities_with_upper = cities.map { |city| city.capitalize }
# ['Brno, 'Praha', 'Ostrava', 'Olomouc', 'Postoloprty']
```

** inject
```ruby
def factorial(number)
  return 0 if number == 0
  (1..number).inject { |sum, n| sum * n }
end

factorial(4) # 14
factorial(7) # 5_040
```

** delete_if
```ruby
[1, 2, 3, 4].delete_if { |num| num.odd? }
[1, 2, 3, 4].delete_if { |num| num.even? }
```

** each_with_index
```ruby
positions = Hash.new # {}
%w(tom mrazicz german).each_with_index { |name, index| positions[index] = name }
# { 1 => 'tom', 2 => mrazicz', 3 => 'german' }
```

* hashes

```ruby
options = { :lang => "CZ" }

# or

options = { lang: "CZ" }  # Ruby 1.9 syntax and default hash syntax in Rails from 3.1 under Ruby 1.9
```

  (why symbols as keys?)

* sets (unique arrays)

```ruby
require 'set'

Set.new([:a, :b, :a])
```

#### Useful methods
* `each`
* `include?`
* `map`
* `find`, `find_all`
* `sort`, `sort!`, `sort_by`
* `min`, `max`
* `inject`
* `reverse`, `reverse!`
* `all?`, `any?`
* `zip`

## Příklad

Mějme pole jmén: 
```ruby
[{:name=>"jindra", :age=>21},
 {:name=>"petr", :age=>20},
 {:name=>"pavel", :age=>2},
 {:name=>"barbora", :age=>8},
 {:name=>"pavel", :age=>1},
 {:name=>"leontyna", :age=>21},
 {:name=>"jenovefa", :age=>19},
 {:name=>"mirek", :age=>15},
 {:name=>"patrik", :age=>1}]
```

1/ Vytvořte z tohoto pole pouze pole jmen # ['jindra', 'petr' ....., 'patrik']

2/
Vytvořte hash obsahující skupiny jmen podle jejich délky. Odstraňte ale jména, které jsou kratší než 4 znaky, nebo které obsahují znak 'b'.
Seznam jmén seřaďte on skupiny s nejdelšími jmény ke skupině s nejkratším.
- tip: ||=

```ruby
{ 4 => ['petr'], 5 => ['pavel', 'mirek'] .... }
```

Clone this wiki locally