# Accessing methods from the blocks caller

**URL:** <https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175>\
**Category:** Ruby\
**Created:** [March 18, 2007, 6:31am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175 "2007-03-18T06:31:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 6:31am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/1 "2007-03-18T06:31:42Z")

</div>

Hello,

Sorry if this has been asked many times before, but I’m having a hard  
time  
finding the right keywords to search for this one.

Here’s my question… if I have a method that accepts a block and I want  
to  
call a method of the class I’m in, in that block, how do I do it? See  
the  
comment below in the example. Should make that sentence a bit clearer.  
🙂

class Test  
def method1  
end

```
def method2
    accept_block do # accept_block is not part of the Test class
        ...
        method1 # I want to call method1 from the class I'm in, 

```

but  
I’m getting undefined method for method1  
…  
end  
end  
end

I understand why I would be getting this error, but I don’t know how to  
fix  
it. Is there a way to access the caller in the block in order to access  
the  
method of it? Kernel.caller is the closest I found, but it’s not what I  
want.

I hope this makes some sense. The example is a bit contrived, but  
hopefully  
I get the point across.

Thanks,  
Andrew

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 8:56am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/2 "2007-03-18T08:56:49Z")

</div>

Taking a better look at my pickaxe book, it seems as though this is  
simply a  
scoping issue that doesn’t really have a solution. I have a workaround,  
but  
was curious to know if there was a “proper” way to accomplish what I was  
looking for.

Thanks,  
Andrew

“andrew” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:w44Lh.32606$zU1.24952@pd7urf1no…

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 9:03am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/3 "2007-03-18T09:03:50Z")

</div>

In the three cases I could think of, “method1” was always available to  
the block. AFAIK, the block you pass to #accept\_block no matter where  
it is will always be bound to the lexical context you call it in,  
meaning that ‘method1’ will always be available unless you do  
something special when you call the block.

Maybe it’ll help if you list the source for #accept\_block and the  
exact error you’re getting.

# case 1, ‘accept\_block’ defined in a super class

class S  
def foo; yield; end  
end

# case 2, ‘accept\_block’ defined in an included module

module M  
def bar; yield; end  
end

# case 3, ‘accept\_block’ defined in some other class

class D  
def baz; yield; end  
end

class C \< S  
include M  
def m1; ‘hi’; end  
def test\_foo; foo { m1 }; end  
def test\_bar; bar { m1 }; end  
def test\_baz; D.new.baz { m1 }; end  
end

> > c = C.new  
> > =\> #\<C:0xb7c396e8\>
> 
> > c.test\_foo  
> > =\> “hi”
> 
> > c.test\_bar  
> > =\> “hi”
> 
> > c.test\_baz  
> > =\> “hi”

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 10:45am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/4 "2007-03-18T10:45:55Z")

</div>

$ irb  
irb(main):001:0\> class Test; def method1; end; def method2;  
accept\_block { method1 }; end; end  
=\> nil  
irb(main):002:0\> def accept\_block; yield; end  
=\> nil  
irb(main):003:0\> Test.new.method2  
=\> nil

No error… there’s something weird going on with your version of  
#accept\_block. Care to dump the source out here?

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 11:30am UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/5 "2007-03-18T11:30:58Z")

</div>

On Sun, Mar 18, 2007 at 02:30:04PM +0900, andrew wrote:

> ```
> end
> 
> ```
> 
> end
> 
> I understand why I would be getting this error, but I don’t know how to fix  
> it. Is there a way to access the caller in the block in order to access the  
> method of it? Kernel.caller is the closest I found, but it’s not what I  
> want.

As people have said, this _should_ work. Post a complete example where  
it  
fails, and the error message.

Having said that, if there is a need to, the current object is called  
‘self’  
and can be passed around explicitly if you wish:

class Test  
def accept\_block(some\_object)  
yield some\_object  
end

def method1  
puts “whoo!”  
end

def method2  
accept\_block(self) do |s|  
# …  
s.method1  
# …  
end  
end  
end  
Test.new.method2 # prints “whoo!”

---- But this particular example works without:

class Test  
def accept\_block  
yield  
end

def method1  
puts “whoo!”  
end

def method2  
accept\_block do  
# …  
method1  
# …  
end  
end  
end  
Test.new.method2 # prints “whoo!”

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 9:41pm UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/6 "2007-03-18T21:41:16Z")

</div>

On Mon, Mar 19, 2007 at 05:20:05AM +0900, andrew wrote:

> end
> 
> I fix this by doing this…  
> def some\_action  
> str = render\_to\_string  
> render :update to |page|  
> # use str in the block  
> end  
> end

This is a rails issue. The _controller_ and the _view_ are two separate  
objects; methods defined in the controller are not by default available  
in  
the view.

The preferred solution is usually to define render\_to\_string as a helper  
in  
app/helpers/mys.rb (as long as it’s needed only by the view, not by the  
controller itself)

If you must define it in the controller for some reason, then you can  
make  
it available in the view by

```
def render_to_string
  ...
end
helper_method :render_to_string

```

> I can ask this in a rails group now if you think it’s off topic.

It’s definitely a rails issue - further questions would best be asked  
there.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 9:22pm UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/7 "2007-03-18T21:22:14Z")

</div>

I’m experiencing the issue using Rails. I wanted to leave mention of  
Rails  
out of my post as I figured it was simply a Ruby issue, but perhaps not.

class MyController \< ApplicationController  
def some\_action  
render :update do |page|  
render\_to\_string # getting an error that  
render\_to\_string  
is undefined  
end  
end  
end

I fix this by doing this…  
def some\_action  
str = render\_to\_string  
render :update to |page|  
# use str in the block  
end  
end

So for anybody with a bit of rails knowledge, do you know what’s going  
on?  
I can ask this in a rails group now if you think it’s off topic.

Thanks again,  
Andrew

“eden li” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

---

<div class="post-metadata">

**Author:** ![andrew](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/f19dbf/32.png) [@andrew](https://www.ruby-forum.com/u/andrew)\
**Post date:** [March 18, 2007, 9:57pm UTC](https://www.ruby-forum.com/t/accessing-methods-from-the-blocks-caller/89175/8 "2007-03-18T21:57:17Z")

</div>

On Mon, Mar 19, 2007 at 05:40:45AM +0900, Brian C. wrote:

> ```
> def render_to_string
> ...
> end
> helper_method :render_to_string
> 
> ```

Alternatively: I think that _public_ methods in the controller can be  
accessed from within the view by using the ‘controller’ accessor. e.g.

\<%= controller.render\_to\_string %\>

But this is probably not a good idea if render\_to\_string is a method  
which  
you don’t want to make available to the outside world (in which case you  
should mark it ‘private’)

B.
