読者です 読者をやめる 読者になる 読者になる

Bonkura - Kenny

SIerで働く文系SEの記録

【たのしいRuby_12】数値クラス

Ruby

たのしいRubyの第12章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

Numericのクラス構成

Numericクラス
 -Integerクラス
  -Fixnumクラス
  -Bignumクラス
 -Floatクラス
 -Rationalクラス(有理数)
 -Complex(複素数)
  • IntegerとFloatの計算結果はFloatになる。

メソッド

p 1.2.round #=> 1
p 1.8 round #=> 2

p 1.2.ceil #=> 1
p 1.2.floor #=> 2

Mathモジュール

よく使う数値演算のためのメソッドはMathモジュールで提供されている。

乱数: Random.randメソッド を使う。

1未満の浮動小数点を返す。引数を与えると0からその値より小さい整数を返す。

【たのしいRuby_11】ブロック

Ruby

たのしいRubyの第11章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

ファイルオブジェクト

システム上のファイルを読み書きするためのオブジェクト

file = File.open("sample.txt")
file.each_line do |line|
 print line
end
file.close

# each_line:1行づつ
# each_char:1文字づつ
# each_byte:1バイトづる

イテレータ以外のブロックの使い方

File.openメソッド(自動的にファイルが閉じられる)

File.openメソッドは、ブロックを受け取るとファイルオブジェクトをブロック変数として一度だけブロックを起動する。

File.open("hosts") do |file|
  file.each_line do |line|
    puts line
  end
end

# File#closeを書く必要がない。

ブロック付きメソッドを作る

def total(from,to)
  result = 0
  from.upto(to) do |num|
    if block_given?
      result += yield(num)
    else
      result += num
    end
  end
  return result
end

p total(1,10)
p total(1,10) { |num| num ** 2 }
  • yieldに引数を渡すと、その値がブロック変数としてブロックに渡り、ブロックを実行した結果がyieldの結果として戻ってくる。
  • block_given? は、ブロックが与えられている場合はtrue、与えられていない場合はfalseを返す。

ブロックの実行制御

n = total(1,10) do |num|
  if num == 5
    break
  end
  num
end

p n #=> nilになる
  • ブロックの中でbreakを呼ぶとブロック付き呼び出しの場所まで戻ってくる為、totalメソッドの中で計算の結果を返す処理が全て飛ばされる。

Procオブジェクト

ブロックをオブジェクトとして持ち運ぶ為のクラス。

hello = Proc.new do |name|
  puts "Hello, #{name}."
end

hello.call("World")
hello.call("Ruby")

【たのしいRuby_10】エラー処理と例外

Ruby

たのしいRubyの第10章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

例外

エラー処理をサポートする為の仕組み

begin
 例外を発生させる可能性のある処理
rescue => 例外オブジェクトが代入される変数
 例外が起こった場合の処理
end
#例外が発生したメソッド中にrescue節がない場合は、呼び出し元に遡って探す。」

例外オブジェクトのメソッド

  • class:例外の種類
  • message:例外のメッセージ
  • backtrace:例外の発生した位置情報

ensure(後処理)

例外が起こっても怒らなくても常に実行したい処理

begin
 例外を発生させる可能性のある処理
rescue => 例外オブジェクトが代入される変数
 例外が起こった場合の処理
ensure
 例外の有無に関わらず実行する処理
end

やり直し

resucue節でretryを用いると、begin以下の処理を繰り返す。

begin
 例外を発生させる可能性のある処理
rescue => 例外オブジェクトが代入される変数
 例外が起こった場合の処理
 sleep 10
 retry
end

※beginとendは省略可能!!

rescue修飾子

式1 rescue 式2

n = Integer(val) rescue 0
#valにStringが入ってたら例外が発生し0が代入される。

例外を発生させる

raiseメソッド

【たのしいRuby_9】演算子

Ruby

たのしいRubyの第9章を学んだ。

たのしいRuby 第4版

たのしいRuby 第4版

代入演算子

a += 1
B *= 2

論理演算子

  • 条件1 || 条件2 OR

条件1がfalse,nilの場合のみ条件2を評価する。

  • 条件1 && 条件2 AND

条件2が真の場合のみ条件2を評価する。

  • オブジェクトの存在を確認した上でメソッド呼び出しを行う item = ary && ary[0]

  • 変数デフォルト値のイディオム

var || = 1
# var = var || 1
# varがnil,falseの場合のみ1を代入する。

条件演算子三項演算子

v = (a > b) ? a : b
# 下記と同じ意味
if 条件
 式1
else2
end

範囲演算子

  • 「1..5」:1~5
  • 「1...5」:1~4

【たのしいRuby_8】クラス・オブジェクト指向

Ruby

たのしいRubyの第8章を学んだ。オブジェクト指向を理解する為に大事な内容が詰まっていた。

たのしいRuby 第4版

たのしいRuby 第4版

基本的な用語整理

  • クラス:オブジェクトの種類を表す。雛形・設計図・型みたいなもの。Rubyではオブジェクトは例外なく何らかのクラスに属している。
  • 継承:既に定義されているクラスを拡張して新しいクラスを作ること。
  • サブクラス:継承によって新しく作られたクラス。Rubyの全てのクラスはBasicObjectクラスのサブクラスになっている。
  • スーパークラス:継承のもとになったクラス

クラス

クラス判別メソッド(Objectクラスで定義されている。)

  • instance_of?メソッド:オブジェクトがそのクラスに所属しているか知る
  • is_a?メソッド:継承関係を更にさかのぼってクラスにそのクラスに属しているか調べる

クラスを作る

class クラス名
 クラスの定義
end
# クラス名は大文字から始める。

クラスがnewされたら。。。

下記の場合、インスタンス変数である@nameが"Bob"で初期化される。

〜〜
def initialize(muname="Ruby")
@name = myname
end
〜〜
Hello.new("Bob")

インスタンス変数:@変数名

同じインスタンス内であればメソッド定義を超えてその値を参照できる!

アクセスメソッド

オブジェクトの外部からインスタンス変数にアクセスする事が出来ない為、そのためのメソッドが必要。インスタンス変数name「@name」に対して…

  • attr_reader :name 参照のみ可能。
  • attr_writer :name 書き込みのみ可能
  • attr_accessor :name 参照書き込み可能

上記は、下記を省略した書き方である。

def name
  @name
end

def name=(value)
  @name = value
end
〜
p Hello.name
p Hello.name="Bob"

インスタンスメソッドの中で、メソッドのレシーバ自身のインスタンス変数を参照する

def greet
 puts self.name ※selfは実行メソッドのレシーバ。この場合はputs name でも変わらん
 self.name=test ※name=test だとローカル変数nameに代入することになるのでNG
end

クラスメソッド

クラスそのものをレシーバとするメソッド。newしてインスタンスを生成する必要なし。

class <<  HelloWorld
  def hello(name)
    puts "#{name} Hello"
  end
end

HelloWorld.hello("Ken")

定数

p HelloWorld::Version #=> "1.0"

クラス変数:@@で始まる

そのクラス全てのインスタンスで共有できる変数のこと

メソッドの呼び出すを制限する

無闇にインスタンスメソッドを呼びだされたくない場合の事を考え、3種類のアクセス制限のレベルがある。

def pubend
public :pub

def priend
private :pri

クラスを拡張する

class クラス名 < スーパークラス名
 クラスの定義
end

aliasとundef

モジュール

  • 処理の部分だけをまとめる機能
  • インスタンスを持つことが出来ない
  • 継承出来ない

名前空間

  • Aというモジュールのfooメソッドと、Bというモジュールのfooメソッドは別のものとして扱われる。
  • モジュール内部に名前を定義する事で、名前の競合を防ぐ事が出来る。
  • includeを使うことで、モジュールが持っているメソッド名や定数名を現在の名前空間に取り込める。
p Math::PI
p Math.sqrt(2)

include Math
p PI
p sqrt(2)

モジュールの作成

module HelloModule
  Version = "1.0"

  def hello(name)
    puts "Hello, #{name}"
  end
  # モジュール名.メソッド名の形式で呼び出せるように外部に公開する。
  module_function :hello
end

p HelloModule::Version
HelloModule.hello("Alice")

Mix-in

モジュールをクラスに混ぜ合わせること。クラス定義の中でincludeを使うとモジュールに含まれるメソッドや定数をクラスの中に取り込む事が出来る。

  • クラスは複数スーパークラスを持つことが出来ない(単純継承)ので、複数の機能を共有したい場合に柔軟に対応出来る
  • 同じ機能を持っているけど、同じ種類(クラス)だと考えたくない。

Mix-inした時のメソッド検索のルール

  • Mix-inしても元のクラスで同じ名前のメソッドが定義されいる場合はそちら優先
  • 同じクラスに複数のモジュールをインクルードした場合は、後からインクルードしたもの優先
  • 同じモジュールを2回以上インクルードした場合、2回め以降は無視

オブジェクト指向用語

カプセル化

オブジェクトが管理するデータをオブジェクトの外部から直に操作出来ないようにして、変更したり参照したりするときは必ずメソッドから呼び出すようにする。不整合なデータがオブジェクトに設定されプログラムの挙動がおかしくなる事を防ぐ。

ポリモルフィズム

1つのメソッド名が複数のオブジェクトに属する(そのオブジェクトによって異なる結果が得られる)こと。同じto_sメソッドを使っても、レシーバによって返る値はぜんぜん違うよね。