如何修改实例化的OpenStruct class
How to modify OpenStruct in the instantiated class
我有以下代码,我在其中实例化了一个 returns OpenStruct 结果的对象。
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
我想让 class 工作,这样我就可以即时修改 result
的任何属性。
test = TestModel.new
test.result
=> #<OpenStruct successful?=false>
test.result.successful!
=> #<OpenStruct successful?=true>
此语法来自官方 OpenStruct 页面,它只能独立运行,但不能在实例化的 class - https://ruby-doc.org/stdlib-2.5.3/libdoc/ostruct/rdoc/OpenStruct.html
中运行
result.send('successful?', true)
我也试过lambda
但是没有用
def result
OpenStruct.new(successful?: false, :successful! => lamdba {self.uccessful? = true})
end
有什么想法吗?我真的很想知道怎么做。
OpenStruct requires you to use Object#send 或类似哈希的键来使用谓词符号。文档说:
Hash keys with spaces or characters that could normally not be used for method calls (e.g. ()[]*
) will not be immediately available on the OpenStruct object as a method for retrieval or assignment, but can still be reached through the Object#send method or using []
.
此外,不清楚为什么要将 @result 定义为可写,或者为什么要重写 getter 方法以便 TestModel#result 始终 returns 错误。这可能至少导致了您的部分问题。
相反,我将重写代码如下:
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
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
,但我认为这在语义上更清晰。您在这方面的进展可能会有所不同。
我有以下代码,我在其中实例化了一个 returns OpenStruct 结果的对象。
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
我想让 class 工作,这样我就可以即时修改 result
的任何属性。
test = TestModel.new
test.result
=> #<OpenStruct successful?=false>
test.result.successful!
=> #<OpenStruct successful?=true>
此语法来自官方 OpenStruct 页面,它只能独立运行,但不能在实例化的 class - https://ruby-doc.org/stdlib-2.5.3/libdoc/ostruct/rdoc/OpenStruct.html
中运行result.send('successful?', true)
我也试过lambda
但是没有用
def result
OpenStruct.new(successful?: false, :successful! => lamdba {self.uccessful? = true})
end
有什么想法吗?我真的很想知道怎么做。
OpenStruct requires you to use Object#send 或类似哈希的键来使用谓词符号。文档说:
Hash keys with spaces or characters that could normally not be used for method calls (e.g.
()[]*
) will not be immediately available on the OpenStruct object as a method for retrieval or assignment, but can still be reached through the Object#send method or using[]
.
此外,不清楚为什么要将 @result 定义为可写,或者为什么要重写 getter 方法以便 TestModel#result 始终 returns 错误。这可能至少导致了您的部分问题。
相反,我将重写代码如下:
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
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
,但我认为这在语义上更清晰。您在这方面的进展可能会有所不同。