Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variables in ruby method names

I have the following code:

for attribute in site.device_attributes   device.attribute end 

where I would like the code to substitute the value of "attribute" for the method name.

I have tried device."#{attribute}" and various permutations.

Is this completely impossible? Am I missing something?

I have considered overriding method_missing, but I can't figure out how that would actually help me when my problem is that I need to call an "unknown" method.

like image 260
salt.racer Avatar asked Nov 19 '08 00:11

salt.racer


People also ask

How do you name a method in Ruby?

Ruby allows method names and other identifiers to contain such characters.) Method names may contain letters, numbers, an _ (underscore or low line) or a character with the eight bit set. Method names may end with a ! (bang or exclamation mark), a ? (question mark) or = equals sign.

What are instance variables in Ruby?

What's an instance variable? In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data.

Are all variables objects in Ruby?

A variable itself is not an object. "A variable in Ruby is just a label for a container. A variable could contain almost anything - a string, an array, a hash.


2 Answers

You can use #send method to call object's method by method's name:

object.send(:foo) # same as object.foo 

You can pass arguments with to invoked method:

object.send(:foo, 1, "bar", 1.23) # same as object.foo(1, "bar", 1.23) 

So, if you have attribute name in variable "attribute" you can read object's attribute with

object.send(attribute.to_sym) 

and write attribute's value with

object.send("#{attribute}=".to_sym, value) 

In Ruby 1.8.6 #send method can execute any object's method regardless of its visibility (you can e.g. call private methods). This is subject to change in future versions of Ruby and you shouldn't rely on it. To execute private methods, use #instance_eval:

object.instance_eval {   # code as block, can reference variables in current scope }  # or  object.instance_eval <<-CODE   # code as string, can generate any code text CODE 

Update

You can use public_send to call methods with regard to visibility rules.

object.public_send :public_foo # ok object.public_send :private_bar # exception 
like image 147
Maxim Kulkin Avatar answered Sep 17 '22 15:09

Maxim Kulkin


The "send" method should do what you're looking for:

object = "upcase me!" method = "upcase" object.send(method.to_sym) # => "UPCASE ME!" 
like image 24
Matt Campbell Avatar answered Sep 19 '22 15:09

Matt Campbell