# Inserting surrounding scope into singelton method definition

**URL:** <https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076>\
**Category:** Ruby\
**Created:** [December 12, 2006, 12:56am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076 "2006-12-12T00:56:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sebastia](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a88e57/32.png) [@Sebastia](https://www.ruby-forum.com/u/Sebastia)\
**Post date:** [December 12, 2006, 12:56am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076/1 "2006-12-12T00:56:44Z")

</div>

I have a sorted array (in this case, an ActiveRecord result set) that i  
want to give awareness of its sorting state. I defined a singelton  
method on the array but i can’t figure out how to insert a value from  
the surrounding scope. Below is the best i could come up with, but it  
seems quite horrid (and using plain eval would be even worse i  
suppose). I seem to remember that there was a better way… Anybody?

Thanks,  
Sebastian

sort\_term = “label”  
results = User.find(:all, :order =\> sort\_term)

class \<\< results  
def sorted\_by?  
@sorted\_by\_term  
end  
end

results.instance\_variable\_set("@sorted\_by\_term",sort\_term)

---

<div class="post-metadata">

**Author:** ![Sebastia](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a88e57/32.png) [@Sebastia](https://www.ruby-forum.com/u/Sebastia)\
**Post date:** [December 12, 2006, 1:02am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076/2 "2006-12-12T01:02:45Z")

</div>

Hi –

On Tue, 12 Dec 2006, Sebastia wrote:

> sort\_term = “label”  
> results = User.find(:all, :order =\> sort\_term)
> 
> class \<\< results  
> def sorted\_by?  
> @sorted\_by\_term  
> end  
> end
> 
> results.instance\_variable\_set("@sorted\_by\_term",sort\_term)

To get through the barrier of the class and def scopes, you can use  
class\_eval and define\_method:

(class \<\< results; self; end).class\_eval do  
define\_method(:sorted\_by?, sort\_term)  
end

or something along those lines.

David

---

<div class="post-metadata">

**Author:** ![Sebastia](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a88e57/32.png) [@Sebastia](https://www.ruby-forum.com/u/Sebastia)\
**Post date:** [December 12, 2006, 1:50am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076/3 "2006-12-12T01:50:54Z")

</div>

Wonderful! For some reason the 2-argument notation in your example  
didn’t work for me, but with a Proc as the method definition body all  
is dandy. I had tried class\_eval before but ignorantly used it on the  
array instance instead, which of course doesnt work. So, thanks very  
much for your help.

Here’s the final code:

returning find(:all, :order =\> “#{sort\_by\_term} #{sort\_order\_term}”) do  
|results|  
(class \<\< results; self; end).class\_eval do  
define\_method(:sorted\_by?) { sort\_by\_term }  
define\_method(:sort\_order?) { sort\_order\_term }  
end  
end

On 2006-12-11 18:02:34 -0600, removed\_email\_address@domain.invalid said:

---

<div class="post-metadata">

**Author:** ![Sebastia](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a88e57/32.png) [@Sebastia](https://www.ruby-forum.com/u/Sebastia)\
**Post date:** [December 12, 2006, 2:14am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076/4 "2006-12-12T02:14:56Z")

</div>

Hi –

On Tue, 12 Dec 2006, Sebastian wrote:

> Wonderful! For some reason the 2-argument notation in your example didn’t  
> work for me, but with a Proc as the method definition body all is dandy. I  
> had tried class\_eval before but ignorantly used it on the array instance  
> instead, which of course doesnt work. So, thanks very much for your help.

Yes, I used the wrong construct – I’m glad you figured it out 🙂

David

---

<div class="post-metadata">

**Author:** ![Sebastia](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/a88e57/32.png) [@Sebastia](https://www.ruby-forum.com/u/Sebastia)\
**Post date:** [December 12, 2006, 3:23am UTC](https://www.ruby-forum.com/t/inserting-surrounding-scope-into-singelton-method-definition/79076/5 "2006-12-12T03:23:02Z")

</div>

On Tue, 12 Dec 2006, Sebastia wrote:

> sort\_term = “label”  
> results = User.find(:all, :order =\> sort\_term)
> 
> class \<\< results  
> def sorted\_by?  
> @sorted\_by\_term  
> end  
> end
> 
> results.instance\_variable\_set("@sorted\_by\_term",sort\_term)

why not just use an attr

results = User.find :all, :order =\> sort\_term

class \<\< results  
attr\_accessor ‘sorted\_by’  
alias\_method ‘sorted\_by?’, ‘sorted\_by’  
end

results.sorted\_by = “label”

othewise you need to use module\_eval and define\_method due to the  
scoping.

-a
