LoginSignup
2
3

More than 3 years have passed since last update.

RubyでScalaのケースクラスっぽいことがしたかったのでStructを使えばよかった

Last updated at Posted at 2016-10-09

Scalaのcase classが好き。一行ぱぱっと書くだけで型の恩恵を受けられるのが最高。
Rubyでもそういうのが欲しくなったので第一弾として単純なイミュータブルなコンテナとしての型を定義してみる。
単純にハッシュを使うとかhashieを使うとかでも結果の用途として同じようなことができるけど型が欲しいのです。

追記

コメントで教えてもらいましたが、Struct でやりたいことができるのでした。Qiitaに書いてよかった!

追記ここまで

普通に書くとこんな感じになるはず。

class Food
  attr_reader :price, :name
  def initialize(price, name)
    @price = price
    @name = name
  end
end

ちょっと長いので一行で書きたい。
なのでこんなヘルパーメソッドを定義する。

def case_class(*args)
  claz = Class.new
  claz.send :define_method, :initialize, Proc.new do |*iargs|
    args.each_with_index do |arg, idx| 
      self.instance_variable_set("@#{arg}", iargs[idx])
    end
  end
  args.each do |arg|
    claz.send :define_method, arg, Proc.new do
      self.instance_variable_get("@#{arg}")
    end
  end
  claz
end

こんな使い方ができるようになった。

[161] pry(main)> Person = case_class :name, :age
=> Person
[162] pry(main)> p1 = Person.new('Adam', 30)
=> #<Person:0x007fdec619be80 @age=30, @name="Adam">
[163] pry(main)> p2 = Person.new('Bob', 14)
=> #<Person:0x007fdec53c29d0 @age=14, @name="Bob">

今日はここまで。

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3