-
Notifications
You must be signed in to change notification settings - Fork 5
Lecture 01
autumncollection edited this page Feb 2, 2016
·
4 revisions
- 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
- 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
- methods, variables, files
- snakes_style
- classes and modules
- CamelCaseStyle
- constants
- UPPER_CASE_SNAKES
- 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-
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 }" }- 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- almost, but not quite, entirely unlike strings
-
:namevs."name"-
:nameis immutable -
:nameis 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 -
not-true - only
falseornil -
true - everything else (
true,'',0,[], ...) -
&&,||- recommended for Boolean operations in conditions (higher priority)
puts "Secure password" if p.size > 300 && p !~ /^[a-z]*$/-
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- definitions
class Phone
attr_accessor :name
attr_reader :number
def initialize(name, number)
@name, @number = name, number
end
endclass 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
EOSmessage = <<-EOS
"#{ subject }"
Thanks for using Ruby
EOSchomp
"123\n".chomp # => "123"strip
" 123 ".strip # => "123"include?
"12345".include? "234" # => true-
upcase,downcase,start_with?,end_with?
"hello".upcase # => "HELLO"- 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>"]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'] .... }
```