2

If I create a Struct with an attribute which contains a question mark, any instance of that class will not be able to find that method. For e.g.

    Test = Struct.new(:value, :value?)
    t = Test.new(true,true)
    t.value
      => true
    t.value?
    NoMethodError: undefined method `value?' for #<struct Test value=true, :value?=true> 

Any idea ? I am using Ruby 1.9.3-p286.

Mohan
  • 317
  • 3
  • 9
  • The implementation of `Struct` is quite complicated and I do not have the time to determine the exact mechanism of the issue you've encountered... however, question marks are not allowed in Ruby variable names. It seems likely that somewhere between initializing your `Struct` and accessing the `value?` member, this lexical restriction is biting you, perhaps because `Struct` attempts to store its members as instance variables? – mdunsmuir Feb 02 '13 at 03:19
  • @Mohan: mdunsmuir is only partially correct. In Ruby, almost everything is allowed, even methods with names such as `42`, try `o = Object.new; o.define_singleton_method "42" do true end; o.send "42"` :-) – Boris Stitnicky Feb 02 '13 at 03:26
  • @mdunsmuir: No, not right. Ruby allows ? in method names, and instance variable accessors are just methods. However, you cannot have something like `@thing?`. – Linuxios Feb 02 '13 at 06:00
  • @Linuxios Did I say that you cannot have method names containing question marks? I do not believe I did. – mdunsmuir Feb 02 '13 at 06:48
  • @BorisStitnicky Method names with question marks are allowed. Variable names with question marks are not: http://stackoverflow.com/questions/5448938/in-ruby-a-variable-name-cannot-end-with-such-as-has-completed-but-a-meth – mdunsmuir Feb 02 '13 at 08:23
  • @mdunsmuir: Sorry. I ment to just say that they were allowed in method names. My apologies. – Linuxios Feb 02 '13 at 14:17

1 Answers1

3

Yo'll have to concede that some method names in Ruby are special. For example, if you defined method

o = Object.new
def o.kokot= n
  return n + 1
end

And call

o.kokot 1
#=> 1

The result will still be 1, not 2 as you might expect. This is peculiarity of = sign in method names. In your case of Structs, question mark seems to have such peculiarity, too, which prevents you from retrieving value by calling:

t.value?

You have to call

t[:value?]

That's it, have a nice day.

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74