Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > accessing methods from the blocks caller

Reply
Thread Tools

accessing methods from the blocks caller

 
 
andrew
Guest
Posts: n/a
 
      03-18-2007
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


 
Reply With Quote
 
 
 
 
andrew
Guest
Posts: n/a
 
      03-18-2007
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" <(E-Mail Removed)> wrote in message
news:w44Lh.32606$zU1.24952@pd7urf1no...
> 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
>



 
Reply With Quote
 
 
 
 
eden li
Guest
Posts: n/a
 
      03-18-2007
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"

On Mar 18, 1:30 pm, "andrew" <(E-Mail Removed)> wrote:
> 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.



 
Reply With Quote
 
eden li
Guest
Posts: n/a
 
      03-18-2007
$ 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?

On Mar 18, 3:55 pm, "andrew" <(E-Mail Removed)> wrote:
> 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" <(E-Mail Removed)> wrote in message
>
> news:w44Lh.32606$zU1.24952@pd7urf1no...
>
> > 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



 
Reply With Quote
 
Brian Candler
Guest
Posts: n/a
 
      03-18-2007
On Sun, Mar 18, 2007 at 02:30:04PM +0900, andrew wrote:
> 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.


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.

 
Reply With Quote
 
andrew
Guest
Posts: n/a
 
      03-18-2007
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> 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"
>
> On Mar 18, 1:30 pm, "andrew" <(E-Mail Removed)> wrote:
>> 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.

>
>



 
Reply With Quote
 
Brian Candler
Guest
Posts: n/a
 
      03-18-2007
On Mon, Mar 19, 2007 at 05:20:05AM +0900, andrew wrote:
> 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


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.

 
Reply With Quote
 
Brian Candler
Guest
Posts: n/a
 
      03-18-2007
On Mon, Mar 19, 2007 at 05:40:45AM +0900, Brian Candler wrote:
> 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


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.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Methods and blocks - not that clear when blocks passed into Steven Taylor Ruby 9 04-27-2009 08:46 AM
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
procs/blocks - blocks with procs, blocks with blocks? matt Ruby 1 08-06-2004 01:33 AM
Can't get function caller if the caller is from a function within a popup window Mark Javascript 2 04-03-2004 07:57 AM



Advertisments