# Dynamic Method Calls

**URL:** <https://www.ruby-forum.com/t/dynamic-method-calls/186187>\
**Category:** Ruby\
**Created:** [April 1, 2010, 8:17pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187 "2010-04-01T20:17:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 1, 2010, 8:17pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/1 "2010-04-01T20:17:22Z")

</div>

Right now I have some inefficient code that looks like this…

LdapAccount is my model… and record.attributes is a hash of attribute  
name,value pairs.

records.each do |record|  
LdapAccount.create(:uid =\> record.attributes[“uid”].to\_s) do |c|  
c.buildingname = record.attributes[“buildingName”].to\_s if  
record.attributes.has\_key?(“buildingName”)  
[c.cn](http://c.cn) = record.attributes[“cn”].to\_s if  
record.attributes.has\_key?(“cn”)  
c.department = record.attributes[“department”].to\_s if  
record.attributes.has\_key?(“department”)  
c.displayname = record.attributes[“displayName”].to\_s if  
record.attributes.has\_key?(“displayName”)  
c.employeetype = record.attributes[“employeeType”].to\_s if  
record.attributes.has\_key?(“employeeType”)  
c.givenname = record.attributes[“givenName”].to\_s if  
record.attributes.has\_key?(“givenName”)  
c.homedirectory = record.attributes[“homeDirectory”].to\_s if  
record.attributes.has\_key?(“homeDirectory”)  
c.mail = record.attributes[“mail”].to\_s if  
record.attributes.has\_key?(“mail”)  
end  
end

There’s probably 20 or more attributes I’ll eventually be checking…I’m  
working with tens of thousands of records…and not all records have  
values for every attribute. So rather than do all the extra wasted  
work, I’d really like to be able to do something simpler like this…

records.each do |record|  
LdapAccount.create(:uid =\> record.attributes[“uid”].to\_s) do |c|  
record.attributes.each\_pair do |k,v|  
c.k = v  
end  
end  
end

…but I get…  
undefined method `k=’ for #LdapAccount:.....

Did a little research and read about the send method…so I tried  
this…

c.send(k = v)

…but I get… (in this case the String value of v = “smtp.wiu.edu”)  
[“smtp.wiu.edu”] is not a symbol

So I’m not sure I understand how to use the send method in this case.  
Can anyone offer some insight? Am I headed in the right direction or is  
there a better way to do this.

Thanks,  
Matt

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 1, 2010, 8:30pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/2 "2010-04-01T20:30:16Z")

</div>

Hei Matt,

try c.send(k, v)  
I haven’t tried that myself but it looks like what you want to  
accomplish.

Bye!

–  
Andrea D.

> **[GitHub - bolthar/freightrain: Ruby desktop development made easy](https://github.com/bolthar/freightrain)**
>
> Ruby desktop development made easy. Contribute to bolthar/freightrain development by creating an account on GitHub.

> **[using (IMHO)](https://usingimho.wordpress.com)**
>
> Andrea Dallera 's blog

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 1, 2010, 8:36pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/3 "2010-04-01T20:36:07Z")

</div>

Whoopsie, i’m really sorry. It should be something like:

c.send("#{k}=".to\_sym, v)

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 1, 2010, 8:43pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/4 "2010-04-01T20:43:43Z")

</div>

On Apr 1, 2010, at 11:35 , Andrea D. wrote:

> Whoopsie, i’m really sorry. It should be something like:
> 
> c.send("#{k}=".to\_sym, v)

.to\_sym is unnecessary

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 2, 2010, 3:02pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/5 "2010-04-02T15:02:14Z")

</div>

This did it…thanks for the assistance… 🙂

c.send(“#{k.downcase}=”, “#{v}”)

Every record.attributes value is an Array, even if they are  
single-valued. When I store the data into the LdapAccount model…it  
just stores the data as a String. Which is fine for single-valued  
arrays, but the multi-valued is a problem. I could do the following…

c.send(“#{k.downcase}=”, “#{v.inspect}”)

Which would store every single or multi valued array in the model as a  
String like so…  
single: [“SOMEVAL”]  
multi: [“val1”,“val2”,“val3”,etc…]

But that may be more work when I want to pull that data back out at some  
point in the future. Should I store the single valued attributes as a  
plain String and the multi-valued attributes as an Array String like  
above?

Something like this maybe…

LdapAccount.create(:uid =\> record.attributes[“uid”].to\_s) do |c|  
record.attributes.each\_pair do |k,v|  
# v is an array of single or multi attribute values  
if v.size \> 1  
c.send(“#{k.downcase}=”, “#{v.inspect}”)  
else  
c.send(“#{k.downcase}=”, “#{v}”)  
end  
end  
end

Any thoughts?

Thanks,  
Matt

----- Original Message -----  
From: “Ryan D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: “ruby-talk ML” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Thursday, April 1, 2010 1:42:56 PM  
Subject: Re: Dynamic Method Calls

On Apr 1, 2010, at 11:35 , Andrea D. wrote:

> Whoopsie, i’m really sorry. It should be something like:
> 
> c.send(“#{k}=”.to\_sym, v)

.to\_sym is unnecessary

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 2, 2010, 3:52pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/6 "2010-04-02T15:52:00Z")

</div>

Hmmm…can’t seem to make that happen…

class LdapAccount \< ActiveRecord::Base  
serialize :objectclass, Array  
end

I think because I’m wrapping the value in quotes turning the Array v to  
a String when it’s saved in the model…  
c.send(“#{k.downcase}=”, “#{v}”)

Produces…  
objectclass was supposed to be a Array, but was a String

I can’t take the quotes off though because it doesn’t save correctly in  
the database. Using this code, entries end up looking like this when I  
don’t wrap v in quotes.  
c.send(“#{k.downcase}=”, v)

'—

- inetLocalMailRecipient
- person
- posixAccount
- sambaSamAccount
- shadowaccount
- top  
’

Matt

----- Original Message -----  
From: “AMILIN AurÃ©lien” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: “ruby-talk ML” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Thursday, April 1, 2010 3:14:00 PM  
Subject: Re: Dynamic Method Calls

You should try to serialize your array instead of saving it as a string  
if you are using ActiveRecord try this :  
class LdapAccount \< ActiveRecord::Base  
serialize :mails, Array  
end

then when you get the accout from the database :  
my\_account.mails return an Array

Le 01/04/2010 21:59, Matt M. a Ã©crit :

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 2, 2010, 3:16pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/7 "2010-04-02T15:16:17Z")

</div>

You should try to serialize your array instead of saving it as a string  
if you are using ActiveRecord try this :  
class LdapAccount \< ActiveRecord::Base  
serialize :mails, Array  
end

then when you get the accout from the database :  
my\_account.mails return an Array

Le 01/04/2010 21:59, Matt M. a Ã©crit :

---

<div class="post-metadata">

**Author:** ![mattmcswain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@mattmcswain](https://www.ruby-forum.com/u/mattmcswain)\
**Post date:** [April 2, 2010, 3:58pm UTC](https://www.ruby-forum.com/t/dynamic-method-calls/186187/8 "2010-04-02T15:58:26Z")

</div>

c.send("#{k.downcase}=", v) is the right thing to do and it is normal if  
it is saved as :  
'—

- inetLocalMailRecipient
- person
- posixAccount
- sambaSamAccount
- shadowaccount
- top  
’

It’s just because it is saved into the yaml format  
Just get back the LdapAccount you just saved and you will see that the  
objectclass attribute will be an instance of Array

Le 01/04/2010 22:49, Matt M. a Ã©crit :
