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) almost 11 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) almost 11 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) almost 11 years ago
Thanks for mentioning Hashie gem. It does exactly what I need.