11/08/2018, 21:10

Road to ruby silver (part2)

This is just some note for who want to get Ruby Silver certification. :) Part1 2.3. String (文字列) a = "abcd" p a → "abcd" b = "ab""cd" p b → "abcd" b = "ab" 'cd' p b → "abcd" a = 1 p "a = #{a}" → a = 1 p 'a = #{a}' → a = #{a} "100".to_i → ...

This is just some note for who want to get Ruby Silver certification. :)

Part1

2.3. String (文字列)

a = "abcd"
p a → "abcd"
b = "ab""cd"
p b → "abcd"
b = "ab" 'cd'
p b → "abcd"
a = 1
p "a = #{a}"
→ a = 1
p 'a = #{a}'
→ a = #{a}
"100".to_i → 100
"1.9".to_f → 1.9
"10a5".to_i → 10
"10a5".to_f → 10.0
"1.9".to_i → 1
"1.9.a".to_f → 1.9
"1.9.9".to_f → 1.9
Use notation
Content Means
x ?
new line
?
f ?
a bell
s ?
nn Octor notation (n: 0 ~ 7)
xnn Hexa notation (n: 0-9, a-f)
C-x Control + x (x is ASCII chacter)
M-x Meta + x (x is ASCII chacter)
M-C-x Meta + Control + x (x is ASCII chacter)
"101" → "A" (in octal)
"x41" → "A" (in hexa)
Different between p, puts, print
2.3.0 :035 > p "a"
"a"
 => "a"

2.3.0 :036 > print "a
b"
a
b => nil

2.3.0 :037 > puts "a
b"
a
b
 => nil
Here document
2.3.0 :037 > a = 1
2.3.0 :038 > query = <<-SQL
2.3.0 :039">   SELECT * FROM users where id = #{a};
2.3.0 :040"> SQL
 => "SELECT * FROM users where id = 1;
"
2.3.0 :041 >
2.3.0 :042 >   puts query
  SELECT * FROM users where id = 1;
 => nil
2.3.0 :043 > p query
"SELECT * FROM users where id = 1;
"

Different betwwen double quotes and single quotes is explained in here too.

2.3.0 :009 > a = 1

2.3.0 :010 >   query = <<-'SQL'
2.3.0 :011'> SELECT * FROM users
2.3.0 :012'> where id = #{a};
2.3.0 :013'> SQL
 => "SELECT * FROM users
where id = #{a};
"
2.3.0 :014 > puts query
SELECT * FROM users
where id = #{a};
 => nil


 2.3.0 :015 > query = <<-"SQL"
 2.3.0 :016"> SELECT * FROM users
 2.3.0 :017"> where id = #{a};
 2.3.0 :018"> SQL
  => "SELECT * FROM users
where id = 1;
"
 2.3.0 :019 > puts query
 SELECT * FROM users
 where id = 1;
  => nil
Percent notation
2.3.0 :028 > a = %*abcdef*
 => "abcdef"
2.3.0 :029 > p a
"abcdef"
 => "abcdef

2.3.0 :026 > a = %*"abcdef"*
 => ""abcdef""
2.3.0 :027 > p a
""abcdef""
 => ""abcdef""
2.3.0 :035 > a = %[abcdef]
 => "abcdef"
2.3.0 :036 > p a
"abcdef"
 => "abcdef"

2.3.0 :037 > a = %["abcdef"]
=> ""abcdef""
2.3.0 :038 > p a
""abcdef""
=> ""abcdef""

All percent notation formats:

Format The value will be generated Example
% Double quote (1)
%Q Double quote (2)
%q Single quote (3)
%s Symbol (4)
%W Array (5)
%w Array (Same with %W) (6)
%s Export command (7)
%r Regular expression (8)
a = 1

①
2.3.0 :056 > test = %*"#{a}"*
 => ""1""
2.3.0 :057 > p test
""1""

2.3.0 :058 > test = %*'#{a}'*
 => "'1'"
2.3.0 :059 > p test
"'1'"

②
2.3.0 :060 > test = %Q!#{a}!
 => "1"
2.3.0 :061 > p test
"1"

2.3.0 :064 > test = %Q!'#{a}'!
 => "'1'"
2.3.0 :065 > p test
"'1'"

③
2.3.0 :066 > test = %q!'#{a}'!
 => "'#{a}'"
2.3.0 :067 > p test
"'#{a}'"

2.3.0 :068 > test = %q!"#{a}"!
 => ""#{a}""
2.3.0 :069 > p test
""#{a}""

④
2.3.0 :070 > test = %s!"#{a}"!
 => :""#{a}""
2.3.0 :071 > p test
:""#{a}""

⑤
2.3.0 :074 > test = %W('a' "b" 'c' "d")
 => ["'a'", ""b"", "'c'", ""d""]

⑥
2.3.0 :075 > test = %w('a' "b" 'c' "d")
 => ["'a'", ""b"", "'c'", ""d""]

⑦
2.3.0 :084 > %x*ls*
 => "chapter3.md
"
 (Run ls command and print the output)

⑧
2.3.0 :086 > %r*(a-9)+*
 => /(a-9)+/

Operater

2.3.0 :087 > a = "ru" + "by"
 => "ruby"
2.3.0 :088 > a * 3
 => "rubyrubyruby"
2.3.0 :089 > 3 * a
TypeError: String can't be coerced into Fixnum

2.3.0 :090 > a = "ru"
 => "ru"
2.3.0 :091 > a << "by"
 => "ruby"
2.3.0 :092 > p a
"ruby"

Comparison

"a" < "b" → true
"ab" < "ac" → true
"ab" < "abc" → true
"Ab" == "Ab" → true
"Ab" <=> "Ab" → 0

Length and size of string

NOTE: There are some differents between different encoding

"abcdef".length → 6
"日本語".encoding → #<Encoding:UTF-8>
"日本語".length → 3
Print with format: sprintf

Same with printf of C language

# Radices format
sprintf("result: %#b", 12) → "result: 0b1100" (binary)
sprintf("result: %#o", 12) → "result: 014" (octor)
sprintf("result: %#x", 12) → "result: 0xC" (hexa)
sprintf("result: %#X", 12) → "result: 0xC" (Hexa)

# Number of digits
sprintf("result: %02d", 1) → "result: 01"
sprintf("result: %02d", 123) → "result: 123"
sprintf("result: %05.5f", 123.2345678) → "result: 123.23457"  → rounded

Other way: use % symbol

"result: %#b" % 12  → "result: 0b1100"
"result: %05.5f" % 123.2345678 → "result: 123.23457"  → rounded

2.4. Symbol

Generation ways:
foo1 = :"foo1"  → :foo1
foo2 = :"#{foo1}foo2" → :foo1foo2
foo3 = :'foo3' → foo3
foo4 = :foo4 → foo4
foo5 = :"foo1 foo2" → :"foo1 foo2"
foo6 = %s*foo6* → :foo6
foo7 = "foo7".to_sym → :foo7
Different between symbol and string
"foo1".object_id → 70300729983460 # 1st time
"foo1".object_id → 70300733581760 # 2nd time
→ Always create new string object after called string

"foo1" == "foo1" → true
"foo1".equal? "foo1" → false


:foo1.object_id → 1154268 # 1st time
:foo1.object_id → 1154268 # 2nd time
→ Create symbol object only 1 time

:foo1 == :foo1 → true
:foo1.equal? :foo1 → true

★ eql?

"foo1".eql? "foo1" → true
1.0 == 1 → true
(1.0).eql? 1 → false
(1.0).eql? 1.0 → true

"foo1".equal? "foo1" → false
(1.0).equal? 1 → false
(1.0).equal? 1.0 → true

2.5. Variables and value of its

v1 = "test"
v2 = v1

v1.equal? v2 → true

v1 += "test 2"
p v1 → "testtest 2"
p v2 → "test"

Parameter's value in function

①
def func v1
  v1.object_id
end

v1 = "test"
v1.object_id → 70300726236340
func v1 → 70300726236340

②
def func v1
  p v1.object_id
  v1 += "test 2"
  v1.object_id
end

v1 = "test"
v1.object_id → 70300737948960
func v1 → 70300726215520
v1 → "test"

Destruction method sample

v1 = "test1"
v2 = v1
v1.chop
p v1 → "test1"
p v2 → "test1"

v1.chop!
p v1 → "test"
p v2 → "test"

2.6. Array (配列)

①
array = Array.new(2){|index| index + 1}
→ [1, 2]

②
array = Array.new(2, "a")
→ ["a", "a"]
array[0].object_id → 70300726074660
array[1].object_id → 70300726074660
array[0].replace("b")
p a
→ ["b", "b"]

③
array = ["a", "a"]
array[0].object_id → 70300725957160
array[1].object_id → 70300725957140
array[0].replace("b")
p array
→ ["b", "a"]
Subscript operator(添字演算子)
①
array = [1, 2, 3, 4]
array[-1] → 4
array[3] → 4
array[-4] → 1
array[0] → 1

②
array = [0, 1, 2, 3, 4, 5]
array1 = array[2, 3] # 2: from_index, 3: length of new array
→ [2, 3, 4]
p array
→ [0, 1, 2, 3, 4, 5]
p array1
→ [2, 3, 4]

③
a = [0, 1, 2, 3, 4]
a[1, 3] = "a" # 1: from_index, 3: number of elements will be earsed
p a
→ [0, "a", 4]

④
a = [0, 1, 2, 3, 4]
a[1, 3] = ["a", "b"]
p a
→ [0, "a", "b", 4]

⑤
a = [0, 1, 2, 3, 4]
a[1, 3] = "a", "b", "c", "d", "e"
p a
→ [0, "a", "b", "c", "d", "e", 4]
Some ways to set value
①
2.3.0 :197 > a, b, c = 1, 2, 3
 => [1, 2, 3]
2.3.0 :198 > a
 => 1
2.3.0 :199 > b
 => 2
2.3.0 :200 > c
 => 3

②
2.3.0 :201 > def foo
2.3.0 :202?>     return 1, 2, 3
2.3.0 :203?>   end
 => :foo
2.3.0 :205 >   a, b, c = foo
 => [1, 2, 3]
2.3.0 :206 > a
 => 1
2.3.0 :207 > b
 => 2
2.3.0 :208 > c
 => 3
2.3.0 :209 > a, b, c, d = foo
=> [1, 2, 3]
2.3.0 :210 > d

③
2.3.0 :211 > a, b, c = [1, 2, 3]
 => [1, 2, 3]
2.3.0 :212 > a
 => 1
2.3.0 :213 > b
 => 2
2.3.0 :214 > c
 => 3

2.3.0 :215 > (a, b), c = [1, 2], 3
=> [[1, 2], 3]
2.3.0 :216 > a
=> 1
2.3.0 :217 > b
=> 2
2.3.0 :218 > c
=> 3

④
2.3.0 :219 > a = 1, 2, 3
 => [1, 2, 3]
2.3.0 :220 > a
 => [1, 2, 3]

⑤
2.3.0 :221 > a, *b = 1, 2, 3, 4
 => [1, 2, 3, 4]
2.3.0 :222 > a
 => 1
2.3.0 :223 > b
 => [2, 3, 4]

2.3.0 :224 > a, *b, c = 1, 2, 3, 4
=> [1, 2, 3, 4]
2.3.0 :225 > a
 => 1
2.3.0 :226 > b
 => [2, 3]
2.3.0 :227 > c
 => 4

a, *b, *c = 1, 2, 3, 4, 5, 6
→ SyntaxError

⑥
def foo1 a, *b
  foo2 *b
end

def foo2 c, *d
  d
end

foo1(1, 2, 3) → [3]
foo1(1, 2, 3, 4) → [3, 4]
Operate with array
a = [1, 1, 2, 2]
b = [2, 2, 3, 4]

①
a & b → [2]
a | b → [1, 2, 3, 4]
b | a → [2, 3, 4, 1]

②
a + b → [1, 1, 2, 2, 2, 2, 3, 4]
b + a → [2, 2, 3, 4, 1, 1, 2, 2]
a - b → [1, 1]
b - a → [3, 4]

a - [1] → [2, 2]

③
[1, 2] * 3 → [1, 2, 1, 2, 1, 2]
[1, 2, 3] * "/" → "1/2/3"
[1, 2, 3].join("/") → "1/2/3"
for and each
①
for i in [1, 2, 3]
  p i
end
→ ok

②
for i, j in [[1, 2], [3, 4]]
  p i+ j
end

→ ok

③
for i in [1, 2, 3]
  bar = i
end
p bar
→ 3

④
[1, 2, 3].each do |i|
  bar = i
end
p bar
→ NameError

2.7. Hash

①
2.3.0 :005 > hash = Hash.new(4) # 4 is default value
 => {}
2.3.0 :006 > hash
 => {}
2.3.0 :007 > hash[:test]
 => 4
2.3.0 :008 > hash[:test1]
 => 4

2.3.0 :012 > a = Hash[:test1, 1, :test2, 2]
=> {:test1=>1, :test2=>2}1, 1, :test2, 2]

②
def foo a, b, c, d
  c
end

foo(1, 2, foo1: 1, foo2: 1)
→ ArgumentError: wrong number of arguments (given 3, expected 4)

foo(1, 2, {foo1: 1, foo2: 2}, "d")
→ {:foo1 => 1, :foo2 => 2}

2.8. Range

①
(1..5).include? 3 → true
(1..5).include? 6 → false
(1..5).include? 5 → true
(1...5).include? 5 → false
(1...5).include? 1 → true

②
(1..5) == 3 → false
(1..5) === 3 → true
(1..5) === 5 → true
(1..5) === 6 → false
(1...5) === 5 → false
(1...5) === 1 → true

③
a = "abcdef"
a[1] → "b"
a[1..2] → "bc"
a[1..2] → "b"
case
①
case condition
when value1
  ...
when value2
  ...
else
  ...
end

②
case condition
when value1 then; <<command>>
when value2 then; <<command>>
else <<command>>
end

Sample:

case 7
when 1..5 then; p 1
when 5..10 then; p 2
end
→ 2
while, until
①
while <<condition>> do
  ...
end

②
begin
  ...
end while <<condition>>

Sample:

i = 0
begin
  p i
  i += 1
end while(1..4) === i

③
until <<condition>> do
  ...
end

2.9. RegularExpression (正規表現)

①
/Ruby/ → /Ruby/
%r(Ruby) → /Ruby/
Regexp.new "Ruby" → /Ruby/

②
/Ruby/ === "I love Ruby"
→ true
"I love Ruby" === /Ruby/
→ false

③
/Ruby/ =~ "Version of Ruby: 2.3"
→ 11
"Version of Ruby: 2.3" =~ /Ruby/
→ 11

$`  → "Version of "
$&  → "Ruby"
$'  → ": 2.3"

2.10. Output command (コマンド出力)

`date`
%x(date)

2.11. Block and Proc

Block
def func x
  x + yield
end

func(3){ 2 }
→ 5

func(3)
→ LocalJumpError: no block given (yield)

def func x
  x
end

func(3) {2}
→ 3
def func y
  y + yield
end

func(1){x = 2}

p x
→ NameError: undefined local variable or method `x'

x = 2
func(1){x += 2} → 5

x → 4
def func a, b
  a + yield(b, 3)
end

func(1, 2){|x, y| x + y}
→ 6
def func
  return 1 if block_given?
  0
end

func(){} → 1
func → 0
Proc

Block become object → proc

proc = Proc.new{|x| p x}
proc.call(1)
→ 1
  • Use proc in block
def func x
  x + yield
end

proc = Proc.new{2}
func(2, &proc)
→ 4
  • Use block in proc
def func x, &proc
  x + proc.call
end

func(1){2}
→ 3
  • lambda
lmd = lambda{|x| p x}
lmd.call(3)
→ 3

★ Different between lambda and proc

①
def func
  proc = Proc.new{return 1}
  proc.call
  2  # do not run to here
end

func  → 1

def func2
  lmd = lambda{return 1}
  lmd.call
  2 # run to here
end

func2  → 2

②
p1 = Proc.new{|x, y| y}
p p1.call(1)
→ nil

l1 = lambda{|x, y| y}
p l1.call(1)
→ ArgumentError
Some method using block
  • each
  • each_with_index
  • each_key
  • upto, downto
  • times

Thread

t = Thread.new do
  p "start"
  sleep 5
  p "end"
end

p "wait"
t.join
3.times do |i|
  Thread.start(i) do |index|
    p "Thread-#{index} start"
  end
end

2.12. Loop break systax (脱出構文)

  • next
  • redo

2.13. Exception

raise ArgumentError, "message"
→ ArgumentError: message

raise ArgumentError.new, "message"
→ ArgumentError: message

err = ArgumentError.new("message")
raise err
→ ArgumentError: message

raise "message"
→ RuntimeError: message
  • Catch exception
①
begin
  1 / 0
  1
rescue
  0
end

→ 0

②
b2.3.0 :141 > begin
2.3.0 :142 >       p 1
2.3.0 :143?>   rescue
2.3.0 :144?>     p 0
2.3.0 :145?>   else
2.3.0 :146 >       p 2
2.3.0 :147?>   ensure
2.3.0 :148 >       p 3
2.3.0 :149?>   end
1
2
3
 => 2

③
1 / 0 rescue p 1
→ 1
2.3.0 :151 > begin
2.3.0 :152 >       1 / 0
2.3.0 :153?>   rescue ZeroDivisionError
2.3.0 :154?>     p $!.class
2.3.0 :155?>     raise
2.3.0 :156?>   end
ZeroDivisionError
ZeroDivisionError: divided by 0
a = 0
begin
  b = 1 / a
rescue ZeroDivisionError
  a += 1
  retry
ensure
  p b
end

 => 1
Exception class structure
  • Exception
    • ScriptError
    • SyntaxError
    • SignalException
    • StandardError
    • ArgumentError
    • RuntimeError
    • NameError
      • NoMethodError
    • ZeroDivisionError
Catch, throw
def foo
  throw :exit
end

catch(:exit) {
  a = 5
  foo
  a = 3 → this is not executed
}

p a
→ NameError: undefined local variable or method `a'
0