-1

I want to add a singleton method code to the String object b = 'text'. It should be able to refer to the hash a defined in the local scope. But my attempt results in an error:

a = {'code'=>200, 'body'=>'text'}
b = a['body']

def b.code
  return a['code']
end

p b.code 

# => 'code': undefined local variable or method `a' for "text":String (NameError)

How can I make this work?

user513951
  • 12,445
  • 7
  • 65
  • 82
bioffe
  • 6,283
  • 3
  • 50
  • 65

2 Answers2

3

Adding a singleton method that holds a reference to a local variable isn't idiomatic Ruby, but you can do it. You just have to define the method using a block, and the closure will remember the value of a.

a = { 'code' => 200, 'body' => 'text' }
b = a['body']

b.send(:define_singleton_method, :code) { a['code'] }

b.code # => 200
user513951
  • 12,445
  • 7
  • 65
  • 82
  • This is practically it. I am reconstructing http::Response stub for my caching framework . I don't want my class to be instantiable, so I am trying to create an anonymous class that would satisfy the contract. Also I am trying to understand the principles of ruby inheritance and the scope. Does it have to be singleton? I am very bothered by it. I understand that a module can be loaded only once, therefor every module class definition is a singleton too? Isn't it? – bioffe May 01 '15 at 01:49
  • That's a complicated set of questions. I'm not sure you've been given 100% accurate information regarding modules just yet. There is definitely an easy way to do what you're attempting that shouldn't be quite so bothersome. – user513951 May 01 '15 at 03:17
1

a should be passed as an argument to the method scope or be declared in the method to have local method scope from the beginning (now it is out of scope so it is not recognized in the method). Another option is to declare a globally with $, it should suppress the error from being raised (but results in a bad example of global variable using).

potashin
  • 44,205
  • 11
  • 83
  • 107
  • Yes. It's a terrible solution. The same code would work in Python, JavaScript, obj-c, and probably with Java. So how do we construct methods dynamically in Ruby? – bioffe May 01 '15 at 00:07
  • 3
    @bioffe Isn't your question what you are doing wrong? Don't ask a new question in the comment. – sawa May 01 '15 at 00:11