Practice_Ruby/ドットインストール「Ruby入門」を一通り見てみたのでメモ

これからRubyの勉強をしていくにあたり,いつも通りまずはドットインストールRuby入門に一通り目を通し,Rubyの雰囲気を掴むことにした.

以下に,全体を通して自分が重要だと感じた点,またこれまで学習してきた言語(C, Java, Python)とは少し違うなと感じた点をメモしておく.

ちょっとRubyを動かしたいときの irb コマンド

irb: Interactive Rubyの略

rubyがインストールされていれば,terminal上で以下のようにirbと打つだけでRubyのプロンプトが現れる.ちょっと何かを試したいときに便利.

$ irb

ちなみに,irbコマンド実行時にはホームディレクトリ下の”.irbrc”というファイルが読み込まれる.このファイルを編集することでirbのカスタマイズもできるらしい.以下参考サイトにもう少し詳細なことが書いてある.

参考サイト: https://docs.ruby-lang.org/ja/latest/library/irb.html

コマンドの実行方法

以下のように,ruby “rubyファイル名”のように書けば良い.

$ ruby hello.rb
# hello.rb
print "hello world"

変数と定数の書き方

  • 変数は小文字で e.g. msg, name, x, y
  • 定数は大文字で e.g. VERSION, NUM

なお定数でも値の再代入は可能.ただし,書き換えようとすると警告が出る,

コメントアウト

単数行のコメントアウト

単数行のコメントアウトは”#”で可能

# コメント

複数行のコメントアウト

複数行のコメントアウトは少し変わっていて,以下のように記述する必要がある.

=begin
コメント1行目
コメント2行目
・・・
=end

少し面倒くさい.

printについて

標準出力には以下のようにいくつかの書き方がある.

print "hello world" # そのまま print
puts "hello world" # 出力 + 改行
p "hello world" # デバッグ用 出力するオブジェクトの種類により,結果が異なる.文字列なら"文字列"のように出力される

‘シングルクオーテーション’と”ダブルクオーテーション”の違い

上ではprint,putsの後ろにはダブルクオーテーションを使用したが,ここは必ずしもダブルクオーテーションである必要はなく,シングルクオーテーションも使うことができる.

しかし,Rubyにおいてシングルクオーテーションとダブルクオーテーションの間には以下のような違いがあるので注意する必要がある.

  • “ダブルクオーテーション”は特殊文字を使える,式展開される(評価したい式の前に”#{}”をつける)
  • ‘シングルクオーテーション’は特殊文字は使えない,式展開もされない

%記法

文字列の中に区切り文字(クオーテーション)あると,いちいちバックスラッシュを書いたりしないといけないので面倒くさい.そういう時は,%記法を使うことでスッキリ記述することができる.

また,配列の記述やシステムコマンドを実行してその結果を定数もしくは変数に代入したい場合などにも%記法が使われる..

puts "hello \"world\"!" # (式展開される)
# 上の文は以下のように書き換えることができる
puts %Q(hello "world")
puts %(hello "world") # Qは省略可能

puts 'hello' # (式展開されない)
# 上の文は以下のように書き換えることができる
puts %q(hello) # 上と同じ

# 配列を記述する際
dp %W(red blue) # 上と同じ

p ['red', 'blue']
p %w(red blue) # 上と同じ

# システムコマンドを実行することもできる
date = %x(date) # コマンドの実行
puts date # Fri Aug 11 23:25:59 JST 2017

参考サイト: http://qiita.com/mogulla3/items/46bb876391be07921743

!が付くメソッド,?が付くメソッド

!が付くメソッドは「破壊的メソッド」と言われており,同名の(!の無い)メソッドに比べてより破壊的な作用をもつ.(メソッドを実行したオブジェクト(インスタンス)自身が影響を受ける).

以下に例を示す.

name = "nobu"
puts name.upcase # NOBU
puts name # nobu
puts name.upcase! # NOBU
puts name # NOBU nameの中身が変わっている

?が付くメソッドは真偽値(true, false)を返すメソッド.

p name.empty? # false
p name.include?("b") # true

シンボルオブジェクトについて

とりあえず,ドットインストールのレッスン内では,ハッシュオブジェクトのkeyにシンボルオブジェクトを使うと動作が高速化するという位の説明しかしていなかったが,少し気になったので調べてみた.

とりあえず,一番重要そうな部分だけ引用.

シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。 同じ内容のシンボルはかならず同一のオブジェクトです。
https://docs.ruby-lang.org/ja/2.4.0/class/Symbol.html

以下のコードも,同じページからの引用.

p "abc" == "abc" #=> true
p "abc".equal?("abc") #=> false
p :abc == :abc #=> true
p :abc.equal?(:abc) #=> true ←同値ならば同一

文字列と一対一対応というのがポイントか.同じ文字列を指す異なる文字列オブジェクトは存在し得るが,同じ文字列を持つシンボルオブジェクトは存在しないということもできる.

ハッシュオブジェクトの使い方

ハッシュオブジェクトの書き方は以下のように複数ある.文字列をキーに持つこともできれば,シンボルをキーに持つこともできる.基本的には処理速度的な観点からシンボルを使うことが推奨されているみたい.

scores = {"hoge" => 200, "huga" => 400} # キーは文字列
scores = {:hoge => 200, :huga => 400} # キーはシンボル
scores = {hoge: 200, huga: 400} # キーはシンボル

そして実は,3番目の書き方と2番目の書き方は同じ.”=>”を書くのは面倒臭いし,書き方的にもPythonと同じで嬉しい.

valueへのアクセスは以下のように行う

# 出力
p scores["hoge"] # key に文字列オブジェクトを使用している場合
p scores[:hoge] # key にシンボルオブジェクトを使用している場合

# value の書き方
scores["hoge"] = 100 # key に文字列オブジェクトを使用している場合
scores[:hoge] = 200 # key にシンボルオブジェクトを使用している場合    

オブジェクトの変換

x = 50
y = "3"

# str to int
p x + y.to_i # 53

# str to float
p x + y.to_f # 53.0

# int to s
p x.to_s + y # "503"

scores = {hoge: 200, fuga: 400}

# hash to array
p scores.to_a # [[:hoge, 200], [:huga, 400]]

# array to hash
p scores.to_a.to_h # {:hoge=>200, :huga=>400}

条件分岐 if, case

条件分岐をしたい場合,if,caseなどが使える.

if

# sample code of 'if' from dotinstall
if score > 80 then
    puts "great!"
elsif score > 60 then
    puts "good"
else
    puts "so so..."
end

# simple version of if
puts "great" if score > 80

case

# sample code of 'case' from dotinstall
signal = gets.chomp # chomp は最後の改行文字を取り除くために入れる
case signal
when "red"
    puts "stop!"
when "green", "blue" # このように ',' を使って複数指定も可能
    puts "go!"
when "yellow"
    puts "caution!"
else
    puts "wrong signal!"

繰り返し while, times, foreach

while

# while
i = 0
while i < 10 do
    puts "#(i) hello"
    i+=1
end

times

# times
10.times do |i|
    puts "#(i) hello"
end

# times do end 省略版
10.times { |i| puts "#(i) hello" }

foreach

# foreach
for i in 15..20 do
    p i
end

for s in ["hoge", "piyo", "huga"] do
    p s
end

for x, y in {hoge: 200, piyo:400} do
    puts "#{x}: #{y}"
end

each を使って foreachを実現

# foreach は内部的にeachを使用しているため,以下のように書き換えることも可能
(15..20).each do |i|
    p i
end

["hoge", "piyo", "huga"].each do |s|
    p s
end

{hoge: 200, huga:400}.each do |x, y|
    puts "#{x}: #{y}"
end

# each 省略版
{hoge: 200, huga:400}.each {|x, y| puts "#{x}: #{y}" }

その他 loop, break, next

i = 0
loop do
    p i
    i += 1
end

# ctrl + c で終了

breakはloopを終了させるために使う.

nextは次のloop処理に移るために使う.

メソッドの定義 ・ 使い方

# 定義
def sayHi(name = "tom") # 引数
    puts "hi! #{name}"
end

# 使い方
sayHi("hoge")
sayHi "hoge" # 曖昧にならない限り,()は省略できるとのこと

クラスの作成 ・ 基本的な使い方

class User

    # クラス変数
    @@count = 0

    # クラス定数
    VERSION = 1.1

    # getter, setterの定義
    attr_accessor :name
    # 下の2つを定義しているのと同じ
    # setter: name = (value)
    # getter: name

    # getter だけで良い場合
    # attr_reader :name

    def initialize(name
        @@count +=1
        @name = name  # インスタンス変数の前には@を付ける.
    end
    def sayHi
        puts "hi! I am #{@name}"
    end

    # クラスメソッド
    def self.info
        puts "User Class. #{@@count} instances."
    end
end

tom = User.new("tom")
tom.sayHi # hi! I am tom
bob = User.new("bob")
bob.sayHi # hi! I am bob
User.info # User Class. 2 instances.

クラスの継承

User: 親クラス Super class
AdminUser: 小クラス Sub Class

class AdminUser < User
    # 独自メソッドを定義
    def sayHello
        puts "Hello from #{name}"
    end

    # オーバーライド
    def sayHi
        puts "hi! from admin!"
    end
end

tom = AdminUser.name("tom")
tom.sayHello
tom.sayHi

アクセス権について

アクセス権は以下の3つに分類できる
– public # defaultでコレ
– protected
– private # initialize()とクラス外メソッドはprivate

protectedの説明は今回ドットインストールでは省略された.

  • publicは各instanceから使用することができる.
  • privateはクラス内,もしくはサブクラス内からのみ参照・オーバーライド可能 (これはJavaとは勝手が異なる点に注意!)
class User
    def sayHi
        sayPrivate
    end
    private
        def sayPrivate
            puts "hi! I am #{self.name}"
        end
end

モジュール

メソッドや定数をモジュールとしてまとめることで,名前の衝突を避け,また同様な機能を複数クラス・モジュール間でうまく使いまわせるようにする.

モジュールはクラスのようにメソッドや定数をまとめることができるが,
インスタンスを作ったり継承することはできない.

# 例1 通常のモジュール使用例
module Movie
    VERSION = 1.1

    def self.encode
        puts "encoding..."
    end

    def self.export
        puts "decoding..."
    end
end

Movie.encode
Movie.export
p Movie::VERSION

# 例2 ミックスイン (1つのモジュールを複数のクラスで使用する)
module debug
    def info
        puts "#{self.class} debug info ..."
    end
end

class Player
    include Debug
end

class Monster
    include Debug
end

Player.new.info
Monster.new.info

例外処理

例外処理は,予期しない処理に対して適切に処理するために必要.

既存の例外クラスを使う場合

x = gets.to_i

begin
    p 100 / x
rescue => ex
    p ex.message # 0 division error!
    p ex.class
    puts "stopped!"
ensure # Errorが起きる/起きないに関わらず最後に実行される
    puts "--- END ---"
end

自前で例外クラスを作る場合

以下のようにして,自分で例外クラスを作り,それをcatchすることも可能

class MyEroor < StandardError; end # StandardErrorを継承

begin
    if x == 3
        raise MyError
    end
rescue MyError
    puts "don't use 3!"
    p ex.message # 0 division error!
    p ex.class
    puts "stopped!"
ensure` # Errorが起きる/起きないに関わらず最後に実行される`
    puts "--- END ---"
end
カテゴリーRuby

“Practice_Ruby/ドットインストール「Ruby入門」を一通り見てみたのでメモ” への2件の返信

    1. コメント頂いていたのに全然気が付きませんでした。
      少しでも参考になる点があれば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です