新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。気づけば社会人3年目に突入。

学習記録:Ruby

[Ruby] クラスとモジュール

内容:4章 クラスとモジュール

クラス
  • classの定義
class クラス名
end
    • クラス名は大文字のアルファベットで始める
    • キャメルケースで記述するのが慣習(例:ClassName)
    • クラス定義内には自由に式を記述可能
    • 定数を定義することはよくある。::演算子で参照可能
class MyClass
  DEFAULT_VALUE = 1234
end

MyClass::DEFAULT_VALUE # => 1234
my_object = MyClass.new
    • initializeメソッドが定義されていれば、呼び出される
class MyClass
  def test_method
    puts 'test_method !'
  end
end
    • メソッド名の末尾には、疑問符や感嘆符を付けることができる
class Bread
  def initialize
    @baked = false
  end

  def bake!
    @baked = true
  end

  def baked?
    @baked
  end
end
str = 'abc'

# 逆さにした文字列を返すメソッド
str.reverse # => "cba"
str # => "abc"

# 逆さにした文字列で自身を更新するメソッド(破壊的なメソッド)
str.reverse! # => "cba"
str # => "cba"
class Rectangle
  attr_accessor :width, :height
end
class Ruler
  attr_accessor :length
  
  def self.pair
    [new, new]
  end
end
    • 2つのRulerオブジェクトを配列で返す
    • Ruler.newの呼び出しは、この例ではRulerクラスがselfなので、レシーバを省略してnewと書ける
    • 特異クラス定義(class << self ... end)を用いても記述可能
class Ruler
...
  class << self
    def part
      [new, new]
    end
    def trio
      [new, new, new]
    end
  end
end
class Hoge
  def private_method
  ...
  end
  private :private_method
end
class Hoge
end

foo = Hoge.new
bar = Hoge.new

# barだけの特異メソッド
def bar.tokui_method
end

# barからは呼べる
bar.tokui_method
# fooからはNoMethodErrorになる
# foo.tokui_method
  • クラス変数
    • クラスとそのサブクラス内をスコープとする
    • 変数名を@@で始める
  • クラス定義のネスト
    • 内部クラス的なものも定義可能
    • ただし、外から::演算子でアクセス可能
モジュール
module モジュール名
end
module Sweet
  class Brownie
  end
end

Sweet::Brownie
module Greetable
  def greet_to(name)
    puts "Hello, #{name}. I'm #{self.class}."
  end
end

class Alice
  include Greetable
end

alice = Alice.new
alice.greet_to 'Bob' # "Hello, Bob. I'm Alice"と表示
    • オーバーライドと中でsuperも使用可能
  • メソッドをオブジェクトに取り込む
    • extendを使う
module Greetable
...
end

o = Object.new
o.extend Greetable

o.greet_to 'Bob'
Math.sqrt(4) # => 2.0

include Math
sqrt(4)
  • 自動ロード
    • autoload:引数のクラス・モジュール名が最初に参照されたときに、外部ファイルを自動的にrequireする
    • 毎回必ずロードするとは限らない外部ファイルの読み込みに使う
    • 頻繁に起動を繰り返すようなアプリケーションで、めったに使わない巨大なライブラリを毎回requireするのはさけたい
# 第一引数はクラス・モジュール名、第二引数にはファイル名
autoload :MySweets, 'my_library/my_sweets
...
MySweets # ここでrequireされる
オブジェクト
  • ほとんどのクラスはObjectクラスから派生したサブクラス
  • オブジェクトの基本的な振る舞い
    • そのオブジェクトの情報を返すメソッドや比較演算子などの機能が実装されている
o = Object.new

o.class
o.is_a?(Object) # Objectのインスタンスか?
o.object_id      # オブジェクト固有のID
o.nil?
o.frozen?         # freezeされているか
  • 必要に応じてサブクラスでオーバーライド可能
    • Object==は同一性を返すが、ほとんどのクラスでは同値性を返すようにオーバーライドされる
  • Object#freezw
    • レシーバへの破壊的な操作(状態を変更する操作)を禁止できる
    • freezeされたオブジェクトを変更しようとすると例外RuntimeErrorが発生
    • 一度freezeされると、二度と変更できない
  • 汚染されたオブジェクト
    • セーフレベル:外部からの入力によって危険な操作が行われることを未然に防ぐ
    • 外部からの入力は汚染されたオブジェクトとして扱われる。もしくはObject#taintで汚染されているオブジェクトに変更できる
    • Object#tainted?で汚染されているか確認できる
    • 汚染されたオブジェクトをもとに生成されたオブジェクトも汚染されたオブジェクトになる
    • デフォルトのセーフレベルは0で、0から4までの段階がある
レベル 概要
0 デフォルト。IOや環境変数コマンドライン引数から得られた文字列には汚染マークがつく
1 0 + 汚染されたオブジェクトを引数としたファイル操作やコマンドの実行などが禁止される
2 1 + プロセスに関する操作も禁止
3 このレベルで生成されたオブジェクトには全て汚染マークがつく。2の制限に加えて汚染の解除などが禁止
4 3 + グローバル変数や汚染されていないオブジェクトの変更などが禁止
    • $SAFEに新しい値を代入することでセーフレベルを上げることができる(下げることはできない)

作業時間

  • 研修用の資料作成:3ポモドーロ
  • Ruby:2ポモドーロ