define(*args) -> Class
[permalink][rdoc][edit]define(*args) {|subclass| block } -> Class
-
Data クラスに新しいサブクラスを作って、それを返します。
サブクラスでは値オブジェクトのメンバに対するアクセスメソッドが定義されています。
Dog = Data.define(:name, :age) fred = Dog.new("Fred", 5) p fred.name # => "Fred" p fred.age # => 5
メンバの値を書き換えることはできません。
Dog = Data.define(:name, :age) fred = Dog.new("Fred", 5) fred.age = 6 # => NoMethodError
メンバを持たないサブクラスも定義可能です。以下のように、パターンマッチに利用できます。
class HTTPFetcher Response = Data.define(:body) NotFound = Data.define def get(url) # ダミーの実装 if url == "http://example.com/" Response.new(body: "Current time is #{Time.now}") else NotFound.new end end end def fetch(url) fetcher = HTTPFetcher.new case fetcher.get(url) in HTTPFetcher::Response(body) body in HTTPFetcher::NotFound :NotFound end end p fetch("http://example.com/") # => "Current time is 2023-01-10 10:00:53 +0900" p fetch("http://example.com/404") # => :NotFound
- [PARAM] args:
- 値オブジェクトのクラスを定義するための可変長引数。Symbol または String を指定します。
- [RETURN]
- Data のサブクラスを返します。
- [EXCEPTION] TypeError:
- 引数に Symbol, String (String に暗黙の型変換が行われるオブジェクトを含む) 以外を指定した場合に発生します。
ブロックを指定した場合
Data.define にブロックを指定した場合は定義した Data をコンテキストにブロックを評価します。また、定義した Data はブロックパラメータにも渡されます。
Customer = Data.define(:name, :address) do def greeting "Hello #{name}!" end end p Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"
なお、Dataのサブクラスのインスタンスを生成する際にオプション引数を使用したいときは、 initialize メソッドをオーバーライドすることで実現できます。
Point = Data.define(:x, :y) do def initialize(x:, y: 0) super end end p Point.new(x: 1) # => #<data Point x=1, y=0> p Point.new(x: 1, y: 2) # => #<data Point x=1, y=2>