Execute block in context of yielding method's module

T

Trans

Mental block. Is there a reasonable way to do this?

def dothis ; puts "NO!" ; end

module M
class << self
def dothis
puts "THIS" + @number.to_s
end
def wrap( n, &yld )
old = @number
@number = n
yld.call
@number = old
end
end
end

M.wrap( 10 ) do
dothis
end

This produces "NO!". How do I get it to execute the block in the
context of M, so that it produces "THIS10" (w/o having to out
M.dothis).

Thanks,
T.
 
D

David A. Black

Mental block. Is there a reasonable way to do this?

def dothis ; puts "NO!" ; end

module M
class << self
def dothis
puts "THIS" + @number.to_s
end
def wrap( n, &yld )
old = @number
@number = n
yld.call
@number = old
end
end
end

M.wrap( 10 ) do
dothis
end

This produces "NO!". How do I get it to execute the block in the
context of M, so that it produces "THIS10" (w/o having to out
M.dothis).

instance_eval is the standard way of changing 'self':

M.instance_eval { wrap(10) { dothis } }


David
 
A

Ara.T.Howard

Hey guys,

I'm very new to ruby.

This is some freaky shite! Could somebody give me a use case as to when I'd
want to do something like this?

Thanks!


harp:~ > cat a.rb
module Connection
class << self
def host arg = nil
@host = arg if arg
@host
end
def port arg = nil
@port = arg if arg
@port
end
def configure &block
instance_eval &block
end
end
end

Connection::configure do
host 'http://codeforpeople.com'
port 80
end

p Connection::host
p Connection::port


harp:~ > ruby a.rb
"http://codeforpeople.com"
80


regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] gmail [dot] com
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
D

David A. Black

Hi --

Hey guys,

I'm very new to ruby.

This is some freaky shite! Could somebody give me a use case as to when I'd
want to do something like this?

Somewhat rarely :) I actually prefer to know what 'self' is when I
write a block. I'm uneasy with the idea that here:

some_method { another_method }

I can't tell by looking who's receiving the another_method message.

A more common idiom is to provide the object so that you can see
exactly who's doing what:

class C
attr_accessor :x
def initialize
yield self
end
end

C.new do |c|
c.x = 1
end

and things like that.


David
 
D

David A. Black

Hi --

Thanks for the reply guys!

This last one looks much better to my eyes, but I'm still having problems.

I like the code I write to tell as much to the reader about what's going on
as it possibly can-right there (without having to jump to other methods, in
other classes, in other modules).

I think I'd probably have a hard time figuring out what:

C.new do |c|
c.x = 1
end

did, without having:

class C
attr_accessor :x
def initialize
yield self
end
end

being directly above it (on the same screen somewhere). It might take a few
more keystrokes to write:

c = C.new
c.x = 1

in general, but to me, it's much more readable.

Actually I just showed the construct without assignment. In full
you'd want to assign it:

mc = MyClass.new do |m|
m.x = 1
end

(Easier to choose names with a multi-letter class name :)

Or if c existed already:

c = nil
C.new do |c| etc.

because the block params pick up any existing variables and use those.
(This may change circa 2.0.)

Also, most of the time you see this, there's more than one assignment
going on in the block, so it has a nice encapsulating feel.

Mind you, all of this would have to go hand-in-hand with
documentation. You probably wouldn't have the method code visible,
but you'd have to know that MyClass.new yielded the new instance.


David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top