Bug #10194
closedOpenStruct does not throw an exception when calling missing method with no arguments.
Description
Below is the sample that shows the problem:
#!/usr/bin/env ruby
require 'ostruct'
class TestMethodMissing < OpenStruct
def initialize ()
super(
{ "foo" => "bar" }
)
end
def main()
self.no_such_method
puts "BUG! Should fail on the previous line"
end
end
TestMethodMissing.new( ).main( )
I expect when calling self.no_such_method
to generate an error.
The error can be traced to ostruct.rb
method_missing
implementation
Here is the dump of the method with >>
showing the trouble line:
def method_missing(mid, *args) # :nodoc:
mname = mid.id2name
len = args.length
if mname.chomp!('=')
if len != 1
raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
end
modifiable[new_ostruct_member(mname)] = args[0]
elsif len == 0
>> @table[mid]
else
err = NoMethodError.new "undefined method `#{mid}' for #{self}", mid, args
err.set_backtrace caller(1)
raise err
end
end
There should be a check that @table[mid]
does not return nil
, and in case of nil
raise an error
Updated by marcandre (Marc-Andre Lafortune) over 9 years ago
- Status changed from Open to Rejected
It would have been a possible design choice to prevent calling a getter unless a member has been previously set.
I believe it is too late for this change though, as it could produce severe incompatibilities.
Updated by avit (Andrew Vit) over 9 years ago
The design of OpenStruct is to allow all method calls. (It is similar to a Hash but with method access.)
You can use a regular Struct if you need strict properties, or something from the Hashie gem might do what you're looking for.
Updated by alex-pub.ruby-bugs@reflexion.net (Alex Pogrebnyak) over 9 years ago
Thanks for mentioning Hashie gem. It does exactly what I need.