學幾招 Ruby 運算子 - 覆寫內建方法


Posted by Nacho on 2020-09-08

Part2 學幾招 Ruby 運算子 - 特殊的 operators

TL;DR

  • 在Ruby的世界,運算子(operator)以物件方法的設計被使用,但也有少數例外!
  • 它既是物件的方法,也可以被覆寫用在自己的類別設計上(定義自己的物件行為)

Overwrite Ruby 運算子的方法

在某些程式語言,運算子一可能會被當成保留字,也就是當編譯程式時,如果用到它們,程式就會跳錯終止。然而,來到Ruby的世界,很多熟悉的運算子,像+, -, *, / 這些稱作數學運算子(Arithmetic Operators)的東西,其實是Ruby物件的方法。

puts 1 + 2  # 加號是數字物件的方法
puts 1.+(2) # 2 被當參數傳給 1 的 + 方法

我自己體會到作為方法有蠻多好處的,首先,就是可以為特定的開發目的overwrite原本的方法,例如可以拿+來加料,或重新定義自己想要的物件行為等。

Overwrite plus operator

class Fruit 
  attr_accessor :name
  def initialize(name)
    @name = name
  end

  def +(other) 
    str1 = "I have a #{other} I have a #{name}..."
    str2 = ""
    3.times { str2 += " #{other} #{name}!" }
    str1 + str2
  end
end
melon = Fruit.new("melon") 
pen = "pen"
puts melon+pen # => I have a pen I have a melon... pen melon! pen melon! pen melon!

Overwrite equals operator

另一個例子,在未覆寫前,回傳false,不相等的原因是兩個都是物件,如果在變數後加上 .object_id,可以看到印出的id也不一樣!

備註:>, <, >=, == 這些邏輯運算子,回傳值是一個布林值。

# not overwrite yet!!
class Fruit
 def initialize(name)
  @name = name
 end
end

orange1 = Fruit.new("orange")
orange2 = Fruit.new("orange")

puts orange1 == orange2 # => false

覆寫後,居然可以回傳true了!不是因為出現什麼神奇魔法,改變了object_id的值,或是改變了物件的記憶體位置,而是,透過改寫方法,讓比較基準換成 name 變數的比較,因此,如果一樣去把兩個物件印出來,兩者的object_id還是不一樣喲!
attr_reader:Ruby的讀取方法產生器(Getter),以下面的例子來說,加上這個,才能用orange1.name拿到name的值;不加,想拿值,就要自己寫讀取的方法(實際上很少人這麼做)!

# overwrite !!!
class Fruit
  attr_reader :name
  def initialize(name)
    @name = name
  end

  def ==(other)
    name == other.name
  end
end

orange1 = Fruit.new("orange")
orange2 = Fruit.new("orange")

puts orange1 == orange2 # => true

好累!今天就寫這樣,下次想寫幾個實際開發上常見且有點tricky的部分!

參考

https://www.rubyguides.com/2018/07/ruby-operators/#Assignment_Operators


#ruby operator #overwrite







Related Posts

Day07 LIFF (LINE Front-end Framework)

Day07 LIFF (LINE Front-end Framework)

[ week 2 ]  打造 JaveScript 的基礎 - 基本運算 &位元運算

[ week 2 ] 打造 JaveScript 的基礎 - 基本運算 &位元運算

每日心得筆記 2020-06-18(四)

每日心得筆記 2020-06-18(四)


Comments