# Metaprogramming, define\_method, and class\_eval issues

**URL:** <https://www.ruby-forum.com/t/metaprogramming-define-method-and-class-eval-issues/186581>\
**Category:** Rails\
**Created:** [April 9, 2010, 4:33am UTC](https://www.ruby-forum.com/t/metaprogramming-define-method-and-class-eval-issues/186581 "2010-04-09T04:33:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![klochner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ad7895/32.png) [@klochner](https://www.ruby-forum.com/u/klochner)\
**Post date:** [April 9, 2010, 4:33am UTC](https://www.ruby-forum.com/t/metaprogramming-define-method-and-class-eval-issues/186581/1 "2010-04-09T04:33:48Z")

</div>

I have a 2-part question here that’s a little tricky and starting to  
make my head hurt.

I’m working on a plugin for personal use, where I have an rclients  
table (not named clients because of conflicts with another plugin),  
and several other models that can have Rclients (polymorphic  
association). I’ve defined a method acts\_as\_client\_entity that will  
set up the necessary associations.

Let me first give my functioning code:

############### join model:  
class ClientEntityAssociation \< ActiveRecord::Base  
belongs\_to :rclient  
belongs\_to :entity, :polymorphic=\>true  
end

################ plugin:  
module ClientEntity  
module ClassMethods  
def acts\_as\_client\_entity

has\_many :client\_entity\_associations, :as=\>:entity,  
:dependent=\>:destroy

has\_many :rclients, :through=\>  
:client\_entity\_associations

has\_one :primary\_client, :through=\>  
:client\_entity\_associations,  
:source  
=\> :rclient, :conditions=\>[“client\_entity\_associations.primary  
= ?”,true]

```
    klass = self.name.tableize
    Rclient.class_eval

```

“has\_many :#{klass}, :through=\>:client\_entity\_associations”

```
    define_method("primary_client=") do |rclient|
      client_entity_associations.update_all("`primary` = false")
      assoc =

```

client\_entity\_associations.find\_by\_rclient\_id(rclient.id)  
if assoc && !assoc.primary  
assoc.update\_attribute :primary,true  
else

# client\_entity\_associations.create(:rclient\_id=\>rclient.id,:primary=\>true) end end end end end

The first part of my question is whether there is a way to pass in a  
reference to the calling class (klass) without first setting it as a  
variable. My understand is that if I used self directly in the  
class\_eval statement, it would evaluate to Rclient.

The second part of my questions is why I had to use define\_method for  
primary\_client= (as opposed to def primary\_client=). I kept getting  
conflicts with the dynamic methods rails created from the statement

has\_one :primary\_client . . .

I would just like to know why define\_method seems to be a little more  
forceful.

My apologies if this is a little unwieldy of a question, and I’m open  
to any comments/criticism on the general approach.

- kevin

---

<div class="post-metadata">

**Author:** ![klochner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ad7895/32.png) [@klochner](https://www.ruby-forum.com/u/klochner)\
**Post date:** [April 9, 2010, 11:11am UTC](https://www.ruby-forum.com/t/metaprogramming-define-method-and-class-eval-issues/186581/2 "2010-04-09T11:11:12Z")

</div>

> The first part of my question is whether there is a way to pass in a  
> reference to the calling class (klass) without first setting it as a  
> variable. My understand is that if I used self directly in the  
> class\_eval statement, it would evaluate to Rclient.

You should use the included callback which includes the class it’s being  
included into

[http://ruby-doc.org/core/classes/Module.html#M001660](http://ruby-doc.org/core/classes/Module.html#M001660)

So your acts\_as\_client\_entity should include the module in to the  
current  
class, then you should do your initialisation in the included method.

> The second part of my questions is why I had to use define\_method for  
> primary\_client= (as opposed to def primary\_client=). I kept getting  
> conflicts with the dynamic methods rails created from the statement
> 
> has\_one :primary\_client . . .
> 
> I would just like to know why define\_method seems to be a little more  
> forceful.

No idea, sorry.

Cheers,

Andy

---

<div class="post-metadata">

**Author:** ![klochner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ad7895/32.png) [@klochner](https://www.ruby-forum.com/u/klochner)\
**Post date:** [April 9, 2010, 8:31pm UTC](https://www.ruby-forum.com/t/metaprogramming-define-method-and-class-eval-issues/186581/3 "2010-04-09T20:31:59Z")

</div>

On Apr 8, 10:32 pm, klochner [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The first part of my question is whether there is a way to pass in a  
> reference to the calling class (klass) without first setting it as a  
> variable. My understand is that if I used self directly in the  
> class\_eval statement, it would evaluate to Rclient.

Maybe, don’t know off hand.

> The second part of my questions is why I had to use define\_method for  
> primary\_client= (as opposed to def primary\_client=). I kept getting  
> conflicts with the dynamic methods rails created from the statement

I _think_ the def method is scoping it inside the proc whereas  
define\_method is actually evaluating it within the context of the  
class\_eval (and therefore getting defined as an instance method of the  
class).

I highly recommend the O’Reilly book, The Ruby P.ming Language  
since it gives details about metaprogramming that’s rarely found  
elsewhere and organized in the same place. There are stuff about how  
to access the variable bindings and may answer your first question as  
well.

Ho-Sheng H.  
[http://hosheng.blogspot.com](http://hosheng.blogspot.com)
