# Lambda/procs and dynamically generated methods

**URL:** <https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136>\
**Category:** Ruby\
**Created:** [February 14, 2008, 6:57pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136 "2008-02-14T18:57:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 6:57pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/1 "2008-02-14T18:57:24Z")

</div>

I’m not sure one way is technically better than the other, so if anyone  
has any input, I’d be glad to hear it.

class Job

def initialize(file = nil)  
raise “need file or block” if fil.nil? || !block\_given?  
@action = block\_given? ? lambda { yield } : eval(“lambda {  
#{IO.read(file)} }”)  
end

def do  
@action.call  
end  
end

or

class Job

def initialize(file = nil)  
raise “need file or block” if fil.nil? || !block\_given?  
action = block\_given? ? lambda { yield } : eval(“lambda {  
#{IO.read(file)} }”)  
self.class.send(:define\_method, :task, action)  
self.class.send(:private, :task)  
end

def do  
task  
end  
end

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 7:02pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/2 "2008-02-14T19:02:06Z")

</div>

please forgive the typos in the original, i should learn not to type the  
code directly into the form.

corrected:

class JobA

def initialize(file = nil)  
raise “need file or block” if file.nil? && !block\_given?  
@action = block\_given? ? lambda { yield } : eval(“lambda {  
#{IO.read(file)} }”)  
end

def do  
@action.call  
end  
end

class JobB

def initialize(file = nil)  
raise “need file or block” if file.nil? && !block\_given?  
action = block\_given? ? lambda { yield } : eval(“lambda {  
#{IO.read(file)} }”)  
self.class.send(:define\_method, :task, action)  
self.class.send(:private, :task)  
end

def do  
task  
end  
end

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 7:36pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/3 "2008-02-14T19:36:39Z")

</div>

This can be done in almost endless different ways of course. Here are  
two other options:

```
class Job
    def initialize(file=nil, &block)
        raise "need file or block" unless file or block
        @file = file
        @block = block
    end

    def do
        if @file
            File.read @file
        else
            @block.call
        end
    end
end

class Job
    def initialize(file=nil, &block)
        raise "need file or block" unless file or block
        @task = block || lambda { File.read file }
    end

    def do
        @task.call
    end
end

```

The second one is a slightly cleaned up version of your first  
proposal.

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 7:41pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/4 "2008-02-14T19:41:24Z")

</div>

On 2/14/08, Chris H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> @action.call  
> end  
> end

I may be missing something important about what you are trying to  
accomplish, but  
what about simply

class Job  
def initialize(file = nil, &block)  
raise “need file or block” if file.nil? && !block\_given?  
@action = block || proc { eval IO.read(file)}  
end  
def do  
@action.call  
end  
end

(I sure hope you trust the contents of ‘file’)  
-Adam

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 7:57pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/5 "2008-02-14T19:57:28Z")

</div>

Adam S. wrote:

> On 2/14/08, Chris H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > @action.call  
> > end  
> > end
> 
> I may be missing something important about what you are trying to  
> accomplish, but  
> what about simply
> 
> class Job  
> def initialize(file = nil, &block)  
> raise “need file or block” if file.nil? && !block\_given?  
> @action = block || proc { eval IO.read(file)}  
> end  
> def do  
> @action.call  
> end  
> end
> 
> (I sure hope you trust the contents of ‘file’)  
> -Adam

The main reason the code is the way it is, is because I don’t want to  
used named blocks, see:

> **[Ruby closures and memory usage](http://ola-bini.blogspot.com/2007/12/ruby-closures-and-memory-usage.html)**
>
> You might have seen the trend - I've been spending time looking at memory usage in situations with larger applications. Specifically the thi...

The only really difference between the 2 is that in once instance I am  
capturing the block in @action and in the other I am creating a method  
from the block. I didn’t know if one way was more efficient than the  
other.

And yes, I will be trusting the code in file. 🙂

I’m not necessarily looking for the simplest solution, I’m looking for  
the best solution. Both of the examples I posted have the same results,  
it’s just how they are implemented. I didn’t know there was some behind  
the scenes mo-jo going on that makes one a better choice than the other.

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 8:30pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/6 "2008-02-14T20:30:04Z")

</div>

> ```
> irb(main):034:0> JobB.instance_method(:do)
> => #<UnboundMethod: JobB#do>
> 
> ```

This should be :task of course. Sorry.

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 8:49pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/7 "2008-02-14T20:49:33Z")

</div>

ThoML wrote:

> Okay, I missed the deeper meaning of eval in your example.
> 
> ```
> eval("lambda {#{IO.read(file)} }")
> 
> ```
> 
> Maybe:
> 
> ```
> @task = if file
> ruby = file.read file
> lambda { eval ruby }
> else
> block
> end
> 
> ```
> 
> > I’m not necessarily looking for the simplest solution, I’m looking for  
> > the best solution. Both of the examples I posted have the same results,  
> > it’s just how they are implemented.
> 
> The second one creates the method in the class though which most  
> likely  
> isn’t what you want.
> 
> ```
> irb(main):032:0> j = JobB.new('test.rb')
> => #<JobB:0x7fec2adc>
> irb(main):034:0> JobB.instance_method(:do)
> => #<UnboundMethod: JobB#do>
> 
> ```
> 
> If you want to minimize the context, create a new method that gets  
> nothing but the file name as argument and returns the block for the  
> file. I think that’s what’s meant in the blog post.

so what would be the difference between:

x = eval “lambda { #{IO.read(file)}” }"  
x.call

y = lambda { eval IO.read(file) }  
y.call

I’m guessing that in the first eval gets called only the one time where  
in the second, eval gets called with every y.call. (this is why i did  
it the way i did, if i am incorrect, then please let me know)

---

<div class="post-metadata">

**Author:** ![bigdaddy71](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bbe5ce/32.png) [@bigdaddy71](https://www.ruby-forum.com/u/bigdaddy71)\
**Post date:** [February 14, 2008, 8:27pm UTC](https://www.ruby-forum.com/t/lambda-procs-and-dynamically-generated-methods/129136/8 "2008-02-14T20:27:40Z")

</div>

Okay, I missed the deeper meaning of eval in your example.

```
eval("lambda {#{IO.read(file)} }")

```

Maybe:

```
@task = if file
            ruby = file.read file
            lambda { eval ruby }
        else
            block
        end

```

> I’m not necessarily looking for the simplest solution, I’m looking for  
> the best solution. Both of the examples I posted have the same results,  
> it’s just how they are implemented.

The second one creates the method in the class though which most  
likely  
isn’t what you want.

```
irb(main):032:0> j = JobB.new('test.rb')
=> #<JobB:0x7fec2adc>
irb(main):034:0> JobB.instance_method(:do)
=> #<UnboundMethod: JobB#do>

```

If you want to minimize the context, create a new method that gets  
nothing but the file name as argument and returns the block for the  
file. I think that’s what’s meant in the blog post.
