具有类型和转换的结构

发布于 2024-12-05 23:20:25 字数 747 浏览 6 评论 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 模块提供的少得多。

当然,我可以自己实现一个提供此转换功能的类,但我宁愿知道这还没有完成,以免重新发明轮子。

提前谢谢。

I am trying to accomplish the following in Ruby:

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

And I would like it to accept both:

person_struct.new "Some Name",10,100000.0

and

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

That is, I'd like it to do data conversion stuff automatically.

I know Ruby is dinamically and I should not care about data types but this kind of conversion would be handy.

What I am asking is something similar to ActiveRecord already does: convert String to thedatatype defined in the table column.

After searching into ActiveModel I could not figure out how to to some TableLess that do this conversion.

After all I think my problem may require much less that would be offered by ActiveModel modules.

Of course I could implement a class by myself that presents this conversion feature, but I would rather know this has not yet been done in order to not reinvent the wheel.

Tks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如梦 2024-12-12 23:20:25

我认为类内部的实现是如此简单,而且根本没有任何开销,所以我根本不明白使用 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 中的实现将更高一层:

  • 为每种类型实现一个转换器。
  • 在类中绑定该转换器的实例。
  • StructWithType 实例(而非类)的 new 实现中使用类的转换器来进行转换。

它的第一个草图可能是这样的:

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[])。

因此,您必须实现结构体的创建、转换器的查找、参数名称的查找以及新实例属性的设置器。抱歉,今天没时间了...
我使用了create,因为new在Ruby中具有不同的含义,我不想把它搞乱。

I think that the implementation inside a class is so easy, and there is no overhead at all, so I don't see the reason to use StructWithType at all. Ruby is not only dynamic, but very efficient in storing its instances. As long as you don't use an attribute, there is none.

The implementation in a class should be:

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

The implementation in StructWithType would then be one layer higher:

  • Implement for each type a converter.
  • Bind an instance of that converter in the class.
  • Use in the new implementation of StructWithType instances (not class) the converters of the class to do the conversion.

A very first sketch of it could go like that:

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

The ideas here are:

  • You have an instance method named create that creates from the factory a new struct instance.
  • The factory iterates through all args (with the index) and searches for each arg the converter to use.
  • It converts the arg with the converter.
  • It stores in the new instance at the argname (method argname[] has to be written) the new value.

So you have to implement the creation of the struct, the lookup for converter, the lookup for the argument name and the setter for the attributes of the new instance. Sorry, no more time today ...
I have used create because new has a different meaning in Ruby, I did not want to mess this up.

み格子的夏天 2024-12-12 23:20:25

我在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

I have found a project in github that fulfill some of my requirements: ActiveHash.
Even though I still have to create a class for each type but the type conversion is free.
I am giving it a try.

Usage example:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文