首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在实例化类中修改OpenStruct

如何在实例化类中修改OpenStruct
EN

Stack Overflow用户
提问于 2021-02-23 04:30:01
回答 1查看 429关注 0票数 0

下面的代码实例化了一个返回OpenStruct结果的对象。

代码语言:javascript
复制
require 'ostruct'

class TestModel
  attr_accessor :result

  def initializer
  end

  def result
    OpenStruct.new(successful?: false)
  end

  def successful!
    result.send('successful?', true)
  end
end

我希望类能够正常工作,这样我就可以动态地修改我的result的任何属性。

代码语言:javascript
复制
test = TestModel.new

test.result
=> #<OpenStruct successful?=false>

test.result.successful!
=> #<OpenStruct successful?=true>

这个语法来自正式的OpenStruct页面,它只是独立工作,而不是在实例化的类- https://ruby-doc.org/stdlib-2.5.3/libdoc/ostruct/rdoc/OpenStruct.html中工作。

result.send('successful?', true)

我也试过使用lambda,但没有用

代码语言:javascript
复制
  def result
    OpenStruct.new(successful?: false, :successful! => lamdba {self.uccessful? = true})
  end

有什么想法吗?我真的很想知道怎么做。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-23 06:20:47

OpenStruct要求您使用Object#send或类似哈希的键来使用谓词符号。文件上说:

具有通常不能用于方法调用(例如()[]*)的空格或字符的散列键作为检索或赋值的方法在OpenStruct对象上不会立即可用,但仍然可以通过Object#send方法或使用[]来达到。

此外,还不清楚为什么要将@结果定义为可写的,或者为什么要重写getter方法,以便TestModel#result总是返回false。这可能至少导致了你的部分问题。

相反,我会按照以下方式重写代码:

代码语言:javascript
复制
require 'ostruct'

class TestModel 
  attr_reader :result

  def initialize
    @result = OpenStruct.new :successful? => nil
  end

  def unsuccessful
    @result.send "successful?=", false
  end
    
  def successful!
    @result.send "successful?=", true
  end
end
代码语言:javascript
复制
test_model = TestModel.new
#=> #<TestModel:0x00007faf5c1b9528 @result=#<OpenStruct successful?=nil>>

test_model.result
#=> nil

test_model.successful!
#=> true

test_model.result
#=> #<OpenStruct successful?=true>

test_model.unsuccessful
#=> false

test_model.result
#=> #<OpenStruct successful?=false>

如果您愿意,当然可以将结构成员初始化为false而不是nil,但我认为这在语义上更清楚。你在这方面的里程可能会有所不同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66327096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档