0

Rubyで次のことを達成しようとしています:

person_struct = StructWithType.new "Person", 
                                   :name => String, 
                                   :age => Fixnum, 
                                   :money_into_bank_account => Float

そして、私はそれが両方を受け入れることを望みます:

person_struct.new "Some Name",10,100000.0

person_struct.new "Some Name","10","100000.0"

つまり、データ変換を自動的に行いたいのです。

私はRubyが動的であることを知っており、データ型を気にするべきではありませんが、この種の変換は便利です.

私が求めているのは、ActiveRecord が既に行っているのと同様のことです: String をテーブル列で定義されたデータ型に変換します。

ActiveModel を検索した後、この変換を行う TableLess の方法がわかりませんでした。

結局のところ、私の問題は、ActiveModel モジュールによって提供されるよりもはるかに少ないものを必要とするかもしれないと思います。

もちろん、この変換機能を提供するクラスを自分で実装することもできますが、車輪の再発明を避けるために、これがまだ行われていないことを知りたいと思います。

よろしくお願いします。

4

2 に答える 2

0

クラス内での実装はとても簡単で、オーバーヘッドがまったくないので、使用する理由がまったくないと思いますStructWithType。Ruby は動的であるだけでなく、そのインスタンスを非常に効率的に格納します。属性を使用しない限り、何もありません。

クラスでの実装は次のようにする必要があります。

def initialize(name, age, money_into_bank_account)
  self.name = name
  self.age = age.to_i
  self.money_into_bank_account = money_into_bank_account.to_f
end

の実装はStructWithType、1 層上になります。

  • タイプごとにコンバーターを実装します。
  • そのコンバーターのインスタンスをクラスにバインドします。
  • newインスタンス (クラスではない) の実装でStructWithType、クラスのコンバーターを使用して変換を行います。

最初のスケッチは次のようになります。

class StructWithType
  def create(args*)
    <Some code to create new_inst>
    args.each_with_index do |arg,index|
      new_value = self.converter[index].convert(arg)
      new_inst[argname[index]]= new_value
    end
  end
end

ここでのアイデアは次のとおりです。

  • ファクトリから新しい構造体インスタンスを作成する create という名前のインスタンス メソッドがあります。
  • ファクトリはすべての引数を (インデックスを使用して) 反復処理し、コンバーターが使用する各引数を検索します。
  • arg をコンバーターで変換します。
  • 新しいインスタンスの argname (メソッドargname[]を記述する必要があります) に新しい値を格納します。

したがって、構造体の作成、コンバーターのルックアップ、引数名のルックアップ、および新しいインスタンスの属性のセッターを実装する必要があります。すみません、今日はもう時間がありません... Ruby では別の意味を持っているcreateのでnew、これを台無しにしたくなかったので使用しました。

于 2011-09-20T14:52:01.830 に答える
0

私の要件の一部を満たすプロジェクトが github で見つかりました: ActiveHash。型ごとにクラスを作成する必要がありますが、型変換は無料です。私はそれを試しています。

使用例:

class Country < ActiveHash::Base
  self.data = [
                {:id => 1, :name => "US"},
                {:id => 2, :name => "Canada"}
              ]
end

country = Country.new(:name => "Mexico")
country.name  # => "Mexico"
country.name? # => true
于 2011-10-13T17:16:52.927 に答える