コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

Rubyにてyield_self/thenを使って普通の戻り値をメソッドチェインのように使う

このエントリはRubyのAdventCalendar2021の13日目の記事です。

書き方として割と見かける事が多いので、こういう使い方もできるよという知識の一つとしてご紹介します。

環境

$ ruby -v
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-darwin19]

今回取り上げるメソッド

Object#then (Ruby 3.0.0 リファレンスマニュアル)

リファレンスとしては then で紹介されているが yield_selfエイリアスとなっている。

どういうときに使えるか

例えば 「対象の変数」の数値に2を加算した数をした数を用意し、その数をその数の分だけ掛け算し、結果の内容を文字列にしたい場合

# 対象の変数はtarget
target = 2

target_plus_two = target + 2
result = (target_plus_two ** target_plus_two).to_s

このようにかけるが変数代入が大変なので、これがyield_selfを使うと以下のように記述できる

target = 2

target.yield_self{|x| x + 2}.yield_self{|x| x ** x}.to_s

使える場面

例えば https://httpbin.org/json にリクエストをすると以下のようなJSONが返ってくる。

{
  "slideshow": {
    "author": "Yours Truly",
    "date": "date of publication",
    "slides": [
      {
        "title": "Wake up to WonderWidgets!",
        "type": "all"
      },
      {
        "items": [
          "Why <em>WonderWidgets</em> are great",
          "Who <em>buys</em> WonderWidgets"
        ],
        "title": "Overview",
        "type": "all"
      }
    ],
    "title": "Sample Slide Show"
  }
}

その際に取得したJSONslideshow.authorという階層の中身を取り、"slide author is #{slideshow.author}" とやりたい場合に愚直に書くと以下のようになる。

require 'open-uri'
require 'json'

url = "https://httpbin.org/json"

response = URI(url).read
parse_hash = JSON.parse(response)
p "slide author is #{parse_hash.dig('slideshow','author')}"

ただ、ここを yield_self/then を使うと以下のようにメソッドチェイン風に書くことができる

require 'open-uri'
require 'json'

url = "https://httpbin.org/json"

URI(url)
  .read
  .then{|response| JSON.parse(response)}
  .dig('slideshow','author')
  .then{|pick_author| p "slide author is #{pick_author}" }

参考サイト