I have a method. object.tap!!!

งานวันนี้ต้องมีการทำ operation กับ hash นิดหน่อย รับ input เป็น hash จากนั้น ทำอะไรบางอย่างกับ value แล้ว return เป็น hash กลับออกมาอีกครั้ง

แรกสุดเลยผมและคู่ pair ทำ version แรกออกมาแบบง่ายและ make sense แก่ชาว dev ที่เกิดบนยุค for loop ที่สุดหน้าตาเป็นดังนี้

1
2
3
4
5
def do_each(hash)
  result = {}
  hash.each { |key, value| result[key] = do_something(value) }
  result
end

แต่พวกเราไม่พอใจ จากที่ Ruby ไม่ต้องมี return เพราะมันจับค่าที่ return จาก expression สุดท้าย เป็นค่า return ของ method ให้เอง เราจึงมองว่า result ตัวสุดท้ายมันเกะกะ (result ตัวแรกก็แอบเกะกะด้วย)

พอเกิดปัญหานี้ เราก็มักจะเปลี่ยนมันเป็น inject ซะ ได้ว่า

1
2
3
def do_inject(hash)
  hash.inject({}) { |result, pair| result[pair.first] = do_something(pair.last); result }
end

แต่ result ตัวสุดท้ายใน block ก็ยังเกะกะอยู่

จากนั้นคู่ pair ของผม นึก method ที่เราต้องการออก มันคือ instance method “tap” คอนเซปก็คือ เราทำอะไรกับมันก็ได้ใน block แล้วมันจะถูก return ออกไป code จึงเปลี่ยนไปเป็นแบบนี้

1
2
3
4
5
def do_tap(hash)
  {}.tap do |result|
    hash.each { |key, value| result[key] = do_something(value) }
  end
end

เหอะๆ ไม่รู้จัก method นี้มากก่อนเลย ตอนนี้บน version control เลยเป็นอันนี้อยู่

ตอนเย็น ระหว่างเดินไปขึ้นรถบัสไปงาน Agile meetup นึกขึ้นได้อีกท่านึง ดูจะสั้นกว่าด้วย

1
2
3
def do_map(hash)
  Hash[hash.map { |key, value| [key, do_something(value)] }]
end

สนุกดีนะครับ 555

 

Advertisements

One thought on “I have a method. object.tap!!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s