Ruby: Dry-rb gemシリーズのラインナップと概要

こんにちは、hachi8833です。 先ごろRubyWorld ConferenceでRuby Prize 2017を受賞された@solnicことPiotr Solnicaさんが近年力を入れているのがdry-rbシリーズです。 @solnicさんはあのVirtusの作者でもあるのですが、現在VirtusのREADMEには、Virtusの機能を分割改良してdry-rbにしたとあります。 Virtusを作ったことで、Rubyにおけるデータの扱い、中でもcoercion/型安全/バリデーションについて多くのことを学べました。このプロジェクトは成功を収めて多くの人々が役立ててくれましたが、私はさらによいものを作ることを決心しました。その結果、dry-types、dry-struct、dry-validationが誕生しました。これらのプロジェクトはVirtusの後継者と考えるべきであり、考慮点やより優れた機能がさらにうまく分割されています。Virtusが解決しようとした同種の現代的な問題について関心がおありの方は、ぜひdryシリーズのプロジェクトもチェックしてみてください。 @solnic https://github.com/solnic/virtus より抄訳 Virtusは長く使われていて枯れているせいか、何年も更新されていません。 また、Virtusの動作が確認されているのはRuby 1.9.3/2.0.0/2.1.2/jrubyであるとのことなので、今後はdry-rbを使うのがよさそうです。そこで、とりあえずどんなgemがあるのかというレベルで少し調べてみました。 なお、dry-rbにはDiscourseで作られたフォーラムがあり、質問にはこちらを使って欲しいそうです。 dry-rbシリーズのラインナップ dry-rb.orgより dry-rbシリーズのgem同士の依存関係だけ、とりあえず.gemspecファイルを元にがんばって図にしてみました(draw.ioで作成)。ざっと見た限りでは、dry-validationとdry-structを使えばVirtusとだいたい同じことができそうです。これらをインストールすると、dry-coreやdry-typeなどの依存gemもインストールされます。 以下はhttp://dry-rb.org/gems/の記載順です。多くのgemは互いに依存関係にあります。11月7日時点のものなので、今後変わる可能性があります。gem名直後のかっこ内はバージョン番号です。 dry-validation(0.11.1) 述語論理に基づいたバリデーションを行うgemです。ドキュメントには、ActiveRecord/ActiveModel::Validationとstrong_parametersより数倍速いとあります(使うかどうかはまた別の問題です)。以下のようなユースケースを含む多くの使いみちがあります。 Form params “GET” params JSON/YAMLドキュメント アプリの設定(ENVに保存されているなど) ActiveRecord/ActiveModel::Validationsの置き換え strong-parametersの置き換え # dry-rb.orgより schema = Dry::Validation.Form do required(:name).filled required(:age).filled(:int?, gt?: 18) end schema.(“name” => “Jane”, “age” => “30”).to_h # => {name: “Jane”, age: 30} schema.(“name” => “Jane”, “age” => “17”).messages # => {:age=>[“must be greater than 18″]} 依存gem ‘concurrent-ruby’, ‘~> 1.0’ ‘dry-configurable’, ‘~> 0.1’, ‘>= 0.1.3’ ‘dry-equalizer’, ‘~> 0.2’ ‘dry-logic’, ‘~> 0.4’, ‘>= 0.4.0’ ‘dry-types’, ‘~> 0.12.0’ ‘dry-core’, ‘~> 0.2’, ‘>= 0.2.1’ dry-types(0.12.2) さまざまなビルトイン型を用いて柔軟な型システムを提供します。利用できる型リストにはTypes::Form::TimeやTypes::Maybe::Strict::IntやTypes::Maybe::Coercible::Arrayといった膨大な種類の型が含まれています。 # dry-rb.orgより require ‘dry-types’ require ‘dry-struct’ module Types include Dry::Types.module end class User < Dry::Struct attribute :name, Types::String attribute :age, Types::Int end User.new(name: ‘Bob’, age: 35) # => #<User name=”Bob” age=35> 依存gem ‘concurrent-ruby’, ‘~> 1.0’ ‘dry-core’, ‘~> 0.2’, ‘>= 0.2.1’ ‘dry-container’, ‘~> 0.3’ ‘dry-equalizer’, ‘~> 0.2’ ‘dry-configurable’, ‘~> 0.1’ ‘dry-logic’, ‘~> 0.4’, ‘>= 0.4.2’ ‘inflecto’, ‘~> 0.0.0’, ‘>= 0.0.2’ dry-struct(0.4.0) structに似たオブジェクトを扱える属性DSLです。constructor_typeで以下を指定することでさまざまな挙動のstructを定義できます。 :permissive: デフォルト :schema :strict :strict_with_defaults :weakと:symbolized 機能が絞り込まれており、属性のwriterは提供されていません(データオブジェクトとしての利用)。そうした目的にはdry-typesが向いているそうです。 # dry-rb.orgより require ‘dry-struct’ module Types include Dry::Types.module end class User < Dry::Struct attribute :name, Types::String.optional attribute :age, Types::Coercible::Int end … Continue reading Ruby: Dry-rb gemシリーズのラインナップと概要