どなブロ

エンジニアァのブログです

たのしいRuby 第9章

8章が長かった分すぐ終わった感

論理演算子の応用

  • 論理演算子を使った演算の特徴
    • 左側の式から順に評価される
    • 論理式の真偽が決定すると、残りの式は評価されない
    • 最後に評価された式の値が論理式全体の値となる

Ex)

条件1 || 条件2

→この場合、条件1・条件2の順番で真偽が判定される →条件1が真ならば、条件2の結果を見ずに全体が真となる

条件1 && 条件2

→この場合は、条件1が真の場合に条件2が評価される

  • 以下のような書き換えができる
name = "Ruby" # nameにデフォルト値設定
if var # varがnilまたはfalseでなければ
  name = var # nameにvarを入れる
end

-> 論理演算子||を使って書き換え

name = var || "Ruby"
  • 別のパターン
item = nil  # itemに初期値を設定
if ary  # aryがnilまたはfalseでなければ
  item = ary.first  # aryの先頭要素を代入
end

-> 変数aryがnilだと、ary.firstでエラーになる。(上記例ではif文で確認している)
-> 論理演算子&&を使って書き換え

item = ary && ary.first

-> さらに短く済ませるためにオブジェクト&.メソッド呼び出しという書き方もある
-> 「安全参照演算子」「nilチェック付きメソッド呼び出し」とか呼ぶ

item = ary&.first
var ||= 1
# var = var || 1 と同じ意味

-> varがnilかfalseの場合に1を代入する、という処理 -> 変数にデフォルト値を与える時の定番の書き方

条件演算子 (三項演算子)

条件 ? 式1 : 式2

-> 以下と同じ意味

if 条件
  式1
else2
end

-> 条件演算子を使って"aとbのうち、大きい方をmaxに代入する"という処理を以下のように書ける

a = 1
b = 2
max = (a > b) ? a : b

範囲演算子

  • rubyには範囲(Range)オブジェクトという、値の範囲を表すオブジェクトがある
Range.new(1,10)

-> これの省略形として用意されているのが範囲演算子

1..10
  • x..yは、xからyまでの範囲。x...yはxからyの1つ手前までの範囲

演算子を定義する

  • ruby演算子の多くはインスタンスメソッドとして実装されているので、ユーザが新たに定義したり再定義したりして意味を変えることができる
  • 再定義できない演算子もある

二項演算子

Ex)

class Point
  attr_accessor :x :y

  def initialize(x=0, y=0)
    @x, @y = x, y
  end

  def inspect # pメソッドで「(x, y)」と表示する
    "(#{x}, #{y})"
  end

  def +(other) # x,yのそれぞれを足す
    self.class.new(x + other.x, y + other.y)
  end

  def -(other)
    self.class.new(x - otehr.x, y - other.y)
  end
end

point0 = Point.new(3, 6)
point1 = Point.new(1, 8)

p point0 # => (3, 6)
p point1 # => (1, 8)
p point0 + point1 # => (4, 14)
p point0 - point1 # => (2, -2)
  • 二項演算子を定義する時は引数名としてotherがよく用いられる

単項演算子

  • 定義可能な単項演算子は、+,-,~,!
  • それぞれ+@,-@,~@,!@という名前で定義できる

Ex) 二項演算子の例のクラスの定義を足す

class Point
  ~~~

  def +@
    dup # 自分の複製を返す
  end

  def -@
    self.class.new(-x, -y) # x,yのそれぞれの政府を逆にする
  end

  def ~@
    self.class.new(-y, x) # 90度反転させた座標を返す
  end
end

point0 = Point.new(3, 6)

p +point0 # => (3, 6)
p -point0 # => (-3, -6)
p ~point0 # => (-6, 3)

添字メソッド

  • 配列やハッシュのobj[i]obj[i]=xのこと
  • [][]=という名前で定義できる
class Point
  ~~~
  def [](index)
    case index
    when 0
      x
    when 1
      y
    else
      raise ArgumentError, "out of range `#{index}`"
    end
  end

  def []=(index, val)
    case index
    when 0
      self.x = val
    when 1
      self.y = val
    else
      raise ArgumentError, "out of range `#{index}`"
    end
  end

point0 = Point.new(3, 6)

p point0[0] # => 3
p point0[1] = 2 # => 2
p point0[1] # => 2
p point0[2] # => エラー(ArgumentError)

感想

  • 論理演算子の応用で簡潔に書けるのいいな〜と
  • 本にも書いてあったけど、複雑なのを三項演算子とかにしちゃうと可読性下がるよね〜
  • 簡単なものなら簡潔に表現していってスッキリしたコードを書きたいですね!

以上