从模块参数动态创建方法

Dynamic method creation from block parameter

提问人:dehelden 提问时间:10/19/2021 更新时间:10/19/2021 访问量:82

问:

我有以下数据结构

array_of_hashes = [{"key"=>"2020-10-01",
  "foo"=>"100",
  "bar"=>38,
  "baz"=>19,
  "losem"=>19,
  "ipsum"=>0,
  ...},
...
]
state =  {["", nil, nil, nil, nil]=>
          #<MySimpleObject:0x0000557fb9fe4708
          @foo=0.0,
          @bar=0.0,
          @baz=0.0,
          @lorem=0.0,
          @ipsum=0.0,
          ...}

array_of_hashes.each_with_object(state) do |stats, memo|
  state = memo['key']

  state.foo = stats['foo'].to_d
  state.bar = stats['bar'].to_d
  state.baz = stats['baz'].to_d
  state.lorem = stats['lorem'].to_d
  state.ipsum = stats['ipsum'].to_d
  ...
end

在这种情况下,我该如何遵循干燥? 我需要 smth 在运行时生成和执行方法,例如:

query.each_with_object(shared_state) do |stats, memo|
  state = memo['key']

  columns = %w[foo bar baz lorem ipsum ...]
  columns.each { |attribute|
    define_method attribute do #??????
      state.attribute = stats[attribute.to_s].to_d
    end
  }
end

据我所知,define_method不适合这种情况。

Ruby-on-Rails Ruby 算法 方法 哈希

评论


答:

2赞 Christian Bruckmayer 10/19/2021 #1

简短的回答,不要!这将使您的代码难以阅读。在我看来,您在第一个示例中拥有的内容完全没问题。不是所有的东西都需要干燥。

如果你真的真的想做,你可以使用send

query.each_with_object(shared_state) do |stats, memo|
  state = memo['key']

  columns = %w[foo bar baz lorem ipsum ...]
  columns.each do |attribute|
    state.send("#{attribute}=", stats[attribute].to_d) 
  end
end

https://apidock.com/ruby/Object/send

评论

0赞 dehelden 10/19/2021
了不起!谢谢!我明白你的意思,我会保持原样:)