2011-01-18 12 views

Trả lời

6

OpenStruct sử dụng một sự kết hợp của define_method cuộc gọi bên trong một séc unless self.respond_to?(name)method_missing. Điều này có nghĩa là nếu tên thuộc tính xung đột với tên của bất kỳ phương thức hiện có nào trên đối tượng thì bạn sẽ gặp phải vấn đề này.

tokland's trả lời nếu tốt nhưng cách khác là để xác định phương pháp id ví dụ:

test.instance_eval('undef id') 

Bạn cũng có thể kết hợp điều này vào phiên bản tùy chỉnh của riêng bạn OpenStruct ví dụ:

class OpenStruct2 < OpenStruct 
    undef id 
end 

irb(main):009:0> test2 = OpenStruct2.new({:id => 666}) 
=> #<OpenStruct2 id=666> 
irb(main):010:0> test2.id 
=> 666 
+0

Nghe có vẻ tốt, bạn không phụ thuộc vào bất kỳ biến cá thể nào (@table, có thể được tái cấu trúc). – tokland

1

Đây là workaround cổ điển, tôi muốn cũng được vui khi nghe một cách tốt hơn:

>> OpenStruct.send(:define_method, :id) { @table[:id] } 
=> #<Proc:[email protected](irb):1> 
>> OpenStruct.new(:id => 666).id 
=> 666 
0

Tôi đã chuyển sang sử dụng Hashery và (phiên bản đổi tên của OpenObject trong phiên bản mới nhất, 1.4) BasicStruct như cho phép tôi làm điều này:

x = BasicStruct.new({:id => 666, :sub => BasicStruct.new({:foo => 'bar', :id => 777})}) 
x.id  # => 666 
x.sub.id # => 777 
x.sub.foo # => "bar" 
Các vấn đề liên quan