Adjusting the Scope of Blocks

Hi,

Is there a way to give a block associated with a method call the same scope
as if it were executing inside the method.

ie.

class Foo
ACONST = 1

def input_flags
@FLAG_SEL = INPUT
yield
end

def output_flags
@FLAG_SEL = OUTPUT
yield
end

def set(flgs)
set_flags(@FLAG_SEL, flgs)
end
end

f = Foo.new

f.input_flags {
set ACONST
}

f.output_flags {
set ACONST
}

Thanks in advance.

Mark Cox

Hi,

Is there a way to give a block associated with a method call the same
scope as if it were executing inside the method.

ie.

class Foo
ACONST = 1

def input_flags
@FLAG_SEL = INPUT
yield
end

def output_flags
@FLAG_SEL = OUTPUT
yield
end

def set(flgs)
set_flags(@FLAG_SEL, flgs)
end
end

f = Foo.new

f.input_flags {
set ACONST
}

f.output_flags {
set ACONST
}

I’ve never done it myself, but you might try:

class Foo
def input_flags(&block)
@FLAG_SEL = INPUT
instance_eval &block
end
end

Gavin

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:49755.203.185.214.34.1070949030.squirrel@webmail.imagineis.com

Hi,

Is there a way to give a block associated with a method call the same
scope as if it were executing inside the method.

ie.

class Foo
ACONST = 1

def input_flags
@FLAG_SEL = INPUT
yield
end

def output_flags
@FLAG_SEL = OUTPUT
yield
end

def set(flgs)
set_flags(@FLAG_SEL, flgs)
end
end

f = Foo.new

f.input_flags {
set ACONST
}

f.output_flags {
set ACONST
}

I’ve never done it myself, but you might try:

This works as expected. Note however that with this approach method local
variables are not accessible.

class Foo
def input_flags(&block)
@FLAG_SEL = INPUT
instance_eval &block
end
end

You can of course yield all values that should be accessible for the
block.

Another approach is to use “eval” with a binding, although be warned that
this can have serious security implications:

def tester(code)
foo=“bar”
b = binding
eval( code, b )
end

tester “puts foo”
=> prints “bar”

But why don’t you just make “input_flags” and “output_flags” accessors to
member variables? Then you can do “foo.input_flags |= Foo::ACONST”.

Or you define a special bit set type:

class Bitset
attr_accessor :val
def initialize(v=0); @val=0; end

def set(x); @val|=x; end
def toggle(x); @val^=x; end
def reset(x); set(x); toggle(x); end
def to_i; val; end
end

Kind regards

robert

Hi –

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:49755.203.185.214.34.1070949030.squirrel@webmail.imagineis.com

[Mark Cox wrote:]

Hi,

Is there a way to give a block associated with a method call the same
scope as if it were executing inside the method.

I’ve never done it myself, but you might try:

class Foo
def input_flags(&block)
@FLAG_SEL = INPUT
instance_eval &block
end
end

This works as expected. Note however that with this approach method local
variables are not accessible.

We had an interesting discussion about this technique
(instance_eval’ing closures) on irc last night. What emerged seemed
to be that the effect of instance_eval is not, strictly speaking, to
execute the block in current scope, but rather to execute it with the
current ‘self’ as ‘self’. I don’t know if there’s a term for that as
concise as ‘scope’; all I can think of is ‘that thing where
instance_eval temporarily changes “self”’…

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

class C
def m(&b)
instance_eval(&b)
instance_eval(“n”)
end

def n
  puts "This is the other #n"
end

end

def n
puts “This is an #n in the block’s scope”
end

l = lambda { n }
l.call
C.new.m &l

=>
This is an #n in the block’s scope
This is the other #n
This is the other #n

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for it
to preserve the context of its creation.

David

···

On Tue, 9 Dec 2003, Robert Klemme wrote:


David A. Black
dblack@wobblini.net

Thanks for your reply.

I’ve written a ruby binding for the low level terminal IO functions
for unix. There is about 60 to 80 constants so I was sort of hoping to
remove the need to do Foo::Const all the time to set flags.

I know I’m just lazy. :slight_smile:

Mark.

Robert Klemme wrote:

···

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:49755.203.185.214.34.1070949030.squirrel@webmail.imagineis.com

Hi,

Is there a way to give a block associated with a method call the same
scope as if it were executing inside the method.

ie.

class Foo
ACONST = 1

def input_flags
@FLAG_SEL = INPUT
yield
end

def output_flags
@FLAG_SEL = OUTPUT
yield
end

def set(flgs)
set_flags(@FLAG_SEL, flgs)
end
end

f = Foo.new

f.input_flags {
set ACONST
}

f.output_flags {
set ACONST
}

I’ve never done it myself, but you might try:

This works as expected. Note however that with this approach method local
variables are not accessible.

class Foo
def input_flags(&block)
@FLAG_SEL = INPUT
instance_eval &block
end
end

You can of course yield all values that should be accessible for the
block.

Another approach is to use “eval” with a binding, although be warned that
this can have serious security implications:

def tester(code)
foo=“bar”
b = binding
eval( code, b )
end

tester “puts foo”
=> prints “bar”

But why don’t you just make “input_flags” and “output_flags” accessors to
member variables? Then you can do “foo.input_flags |= Foo::ACONST”.

Or you define a special bit set type:

class Bitset
attr_accessor :val
def initialize(v=0); @val=0; end

def set(x); @val|=x; end
def toggle(x); @val^=x; end
def reset(x); set(x); toggle(x); end
def to_i; val; end
end

Kind regards

robert

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for it
to preserve the context of its creation.

Essentially it’s not exactly a closure at that point. But that’s not
necessarily bad.

After all, the point of any #eval or variation thereof is to execute the
given code in the
current context (where context might be scope, or merely with the
current self).

In other words, there’s two ways to look at Proc objects. If you’re
using #call, a
Proc is a closure. If you’re using ?_eval a Proc is more along the
lines of “just a
section of code.”

This is the main reason I brought up dynamic scoping and an #eval that
accepts
Proc object to execute a few days ago. To me it seems more elegant to
pass a
“code section object” to #eval than it does to pass a String, and it
isn’t that
inconsistant with what’s already in place.

  • Dan

David A. Black wrote:

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It’s not so far from rebinding a method, though…

“Mark Cox” mark_cox@iprimus.com.au schrieb im Newsbeitrag
news:3fd682a5_1@news.iprimus.com.au…

Thanks for your reply.

I’ve written a ruby binding for the low level terminal IO functions
for unix. There is about 60 to 80 constants so I was sort of hoping to
remove the need to do Foo::Const all the time to set flags.

You could do something like this:

class Foo
FOO = 1
BAR = 2

def set(*flag)
flag = flag[0] if flag.size == 1

case flag
when Symbol, String
  flag = self.class.const_get(flag)
  puts "set flag #{flag}"
when Numeric
  flag = flag.to_i
  puts "set flag #{flag}"
when Enumerable
  flag.each {|f| set(f)}
end

end
end

f=Foo.new
f.set “BAR”
f.set :FOO
f.set [“FOO”, “BAR”]
f.set “FOO”, “BAR”

There’s many routs to Rome…

I know I’m just lazy. :slight_smile:

You really are. Shame on you! :slight_smile:

robert

Mark.

Robert Klemme wrote:

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:49755.203.185.214.34.1070949030.squirrel@webmail.imagineis.com

Hi,

Is there a way to give a block associated with a method call the
same
scope as if it were executing inside the method.

ie.

class Foo
ACONST = 1

def input_flags
@FLAG_SEL = INPUT
yield
end

def output_flags
@FLAG_SEL = OUTPUT
yield
end

def set(flgs)
set_flags(@FLAG_SEL, flgs)
end
end

f = Foo.new

f.input_flags {
set ACONST
}

f.output_flags {
set ACONST
}

I’ve never done it myself, but you might try:

This works as expected. Note however that with this approach method
local
variables are not accessible.

class Foo
def input_flags(&block)
@FLAG_SEL = INPUT
instance_eval &block
end
end

You can of course yield all values that should be accessible for the
block.

Another approach is to use “eval” with a binding, although be warned
that
this can have serious security implications:

def tester(code)
foo=“bar”
b = binding
eval( code, b )
end

tester “puts foo”
=> prints “bar”

But why don’t you just make “input_flags” and “output_flags” accessors
to

···

member variables? Then you can do “foo.input_flags |= Foo::ACONST”.

Or you define a special bit set type:

class Bitset
attr_accessor :val
def initialize(v=0); @val=0; end

def set(x); @val|=x; end
def toggle(x); @val^=x; end
def reset(x); set(x); toggle(x); end
def to_i; val; end
end

Kind regards

robert

“Dan Doel” djd15@po.cwru.edu schrieb im Newsbeitrag
news:3FD5F0F8.3030500@po.cwru.edu…

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for it
to preserve the context of its creation.

Well, is a special kind of closure; a closure that allows through internal
magic that self is temporarily bound to something other than at creation
time (dunny a term for this though). From a theoretical point of view it
might be spooky, but it comes in handy from time to time if you need to
invoke several methods of an instance.

Essentially it’s not exactly a closure at that point. But that’s not
necessarily bad.

After all, the point of any #eval or variation thereof is to execute the
given code in the
current context (where context might be scope, or merely with the
current self).

… or in another context when doing “eval( code, binding )”

In other words, there’s two ways to look at Proc objects. If you’re
using #call, a
Proc is a closure. If you’re using ?_eval a Proc is more along the
lines of “just a
section of code.”

Nicely put.

This is the main reason I brought up dynamic scoping and an #eval that
accepts
Proc object to execute a few days ago. To me it seems more elegant to
pass a
“code section object” to #eval than it does to pass a String, and it
isn’t that
inconsistant with what’s already in place.

Good idea! +1 I was missing exactly that feature the other day. :slight_smile:

Kind regards

robert

Hi –

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for it
to preserve the context of its creation.

Essentially it’s not exactly a closure at that point. But that’s not
necessarily bad.

After all, the point of any #eval or variation thereof is to execute the
given code in the
current context (where context might be scope, or merely with the
current self).

This concept of “context”, though, seems like a bit of a retro-fit;
after all, scope (as reflected in, say, visibility of local variables)
and setting of self (i.e., what’s the default receiver) vary
independently and don’t necessarily fall easily under one master term.
I think that’s what bothers me about this: it strikes me as a hybrid,
ad hoc way to achieve something that is neither really a closure nor
(in my opinion) really in keeping with the usual behavior and purpose
of #instance_eval.

In other words, there’s two ways to look at Proc objects. If you’re
using #call, a
Proc is a closure. If you’re using ?_eval a Proc is more along the
lines of “just a
section of code.”

That’s what I don’t like. (I’m not sure if that means I am purist or
just ignorant of some hybrid computer science concept which makes
sense of this :slight_smile: Actually I feel that “self.instance_eval” should be
a no-op, since what it conveys (absent the magic) is: execute what
follows, setting self to what it already is.

This is the main reason I brought up dynamic scoping and an #eval that
accepts
Proc object to execute a few days ago. To me it seems more elegant to
pass a
“code section object” to #eval than it does to pass a String, and it
isn’t that
inconsistant with what’s already in place.

I may have passed over that thread… I’ll look again.

David

···

On Wed, 10 Dec 2003, Dan Doel wrote:


David A. Black
dblack@wobblini.net

Hi –

“Dan Doel” djd15@po.cwru.edu schrieb im Newsbeitrag
news:3FD5F0F8.3030500@po.cwru.edu…

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for it
to preserve the context of its creation.

Well, is a special kind of closure; a closure that allows through internal
magic that self is temporarily bound to something other than at creation
time (dunny a term for this though). From a theoretical point of view it
might be spooky, but it comes in handy from time to time if you need to
invoke several methods of an instance.

Yikes – spooky magic. Sounds worse and worse :slight_smile:

You’re describing it accurately, but my point is not that I don’t see
what it’s doing but that I don’t like what it’s doing. (See my
response to Dan.)

I wonder whether the saving grace of this might be the & character.
That does at least give a visual cue. But the idea of a closure
becoming “special” based on how it’s treated somewhere else in the
program doesn’t do much for me at this point.

David

···

On Wed, 10 Dec 2003, Robert Klemme wrote:


David A. Black
dblack@wobblini.net

I think that's what bothers me about this: it strikes me as a hybrid,
ad hoc way to achieve something that is neither really a closure nor

Well, it's a closure no ?

(in my opinion) really in keeping with the usual behavior and purpose
of #instance_eval.

and you don't like class_eval ?

Guy Decoux

“David A. Black” dblack@wobblini.net schrieb im Newsbeitrag
news:Pine.LNX.4.44.0312090906230.13718-100000@wobblini.net

Hi –

I had never noticed that closures behave this way when
instance_eval’d. My initial reaction is dislike. To me it feels too
close to having the code in the block interpreted as an eval string.

It feels non-closure-like to me. I don’t see why a block should care
what ‘self’ is at the time it’s called; I thought the point was for
it
to preserve the context of its creation.

Essentially it’s not exactly a closure at that point. But that’s not
necessarily bad.

After all, the point of any #eval or variation thereof is to execute
the
given code in the
current context (where context might be scope, or merely with the
current self).

This concept of “context”, though, seems like a bit of a retro-fit;
after all, scope (as reflected in, say, visibility of local variables)
and setting of self (i.e., what’s the default receiver) vary
independently and don’t necessarily fall easily under one master term.
I think that’s what bothers me about this: it strikes me as a hybrid,
ad hoc way to achieve something that is neither really a closure nor
(in my opinion) really in keeping with the usual behavior and purpose
of #instance_eval.

Yeah, it is hybrid.

In other words, there’s two ways to look at Proc objects. If you’re
using #call, a
Proc is a closure. If you’re using ?_eval a Proc is more along the
lines of “just a
section of code.”

That’s what I don’t like. (I’m not sure if that means I am purist or
just ignorant of some hybrid computer science concept which makes
sense of this :slight_smile:

Of course you are. :-))

/me is rolling his eyes and moving his hands in spooky ways
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.
You like hybrid concepts.

Feel better now? :wink:

Actually I feel that “self.instance_eval” should be
a no-op, since what it conveys (absent the magic) is: execute what
follows, setting self to what it already is.

Not exactly, it overrides any setting of self in the environment that
cometh with the block / closure. IOW, the closure’s env is modified for
this call so that “self” points to the invoking “self” and not the “self”
at the time of definition. So it is not really a noop.

Kind regards

robert
···

On Wed, 10 Dec 2003, Dan Doel wrote:

David A. Black wrote:

This concept of “context”, though, seems like a bit of a retro-fit;
after all, scope (as reflected in, say, visibility of local variables)
and setting of self (i.e., what’s the default receiver) vary
independently and don’t necessarily fall easily under one master term.
I think that’s what bothers me about this: it strikes me as a hybrid,
ad hoc way to achieve something that is neither really a closure nor
(in my opinion) really in keeping with the usual behavior and purpose
of #instance_eval.

But a closure is just code + context. For example, when you implement a
simple Lisp-like
interpreter, the easiest thing to do with a lambda expression is leave
it be, like so:

(lambda () (+ x x)) => (lambda () (+ x x))

Then when you get a lambda expression in the first position in a list,
you just eval the list
with the current environment. This gets you dynamic scoping, the
problem with which is
that:

(foo) and (let ((x 10)) (foo))

are potentially different (because foo’s value of x is whatever the
local value of x is). If you
don’t want dynamic scoping, you need to store the context in which foo
was defined, so you
turn lambda expressions into closures:

(lambda () (+ x x)) => (closure (lambda () (+ x x))
pointer-to-definition-environment)

Now when you call foo, it’s always in the same context. However, you
could theoretically
write an eval that ignores the context, and just evaluates the code in
the current context.

Proc objects are the same way. Code + context. #call works like a
normal closure
(same as calling the method in Scheme), while #?_eval replaces some of
the context.
I don’t know if there is a Lisp/Scheme idiom for this. I’ve not looked
at any Lisp
object systems. Not to mention that Lisp’s main data structure is the
data structure
used to write Lisp code, so it looks more consistent:

(eval '(some code)) or (some-method-that-evals-code a b '(some code))

versus:

eval <<-END_OF_CODE
some code
END_OF_CODE

or

some_method_that_evals_code a, b, <<-END_OF_CODE
some code
END_OF_CODE

That’s what I don’t like. (I’m not sure if that means I am purist or
just ignorant of some hybrid computer science concept which makes
sense of this :slight_smile: Actually I feel that “self.instance_eval” should be
a no-op, since what it conveys (absent the magic) is: execute what
follows, setting self to what it already is.

In some sense it is. self.instance_eval is a no-op with respect to
Strings passed in.
self.instance_eval is a no-op as long as you’re just talking about a
collection of code. It’s only
not a no-op when you take context into account.

I suppose you could make an argument that there should be separate
classes, one a code
object without context, and one a code object with context (possibly
with the latter a child
of the former). However, I don’t think the one without context would be
as generally useful,
and you’d end up with all sorts of confusion (like, you’d want blocks on
methods to be
closures, but then the only way to get a non-closure block would be to
call a method with
a regular block, so non-closure blocks would have to store closure
blocks or something like
that, and it would essentially mean that the #eval-ing of closures would
be covered by a
more complicated system).

I may have passed over that thread… I’ll look again.

The subject at the top of the thread was: Re: Controlled Block Variables

You actually replied to my first post about it basically saying you
didn’t like the idea of
blocks-as-just-code. :slight_smile: Then nothing after that so maybe you didn’t
read anything else.

Anyhow, this post has gone on way too long with my theoretical-ish
ramblings. I don’t
know how big a deal straight #eval of blocks would be (it’s not as
convenient as blocks
given to #instance_eval and #class_eval, which are very handy). I just
don’t like the
look of here-docs as code very much. :slight_smile:

  • Dan

Hi –

I think that’s what bothers me about this: it strikes me as a hybrid,
ad hoc way to achieve something that is neither really a closure nor

Well, it’s a closure no ?

That’s what I’m trying to figure out.

def n; puts “n”; end
x = 1
lam = lambda { n; puts x }

I would expect that, as a closure, lam would always “remember” n and x
from the context of its creation. Apparently it remembers x, but can
be made to forget about n. That what seems very “magic” to me (and
sort of unencapsulated).

I understand that n is a method call and therefore is sensitive to
‘self’ in a way that local variables aren’t; this is what I meant
earlier about scope and self being different concepts. I guess I
don’t like the idea of swapping self inside the block (as opposed to
the ‘self’ in whose context the block is called).

(in my opinion) really in keeping with the usual behavior and purpose
of #instance_eval.

and you don’t like class_eval ?

Uh oh. I sense the beginning of the end :slight_smile: What don’t I (appear to)
like about it?

David

···

On Wed, 10 Dec 2003, ts wrote:


David A. Black
dblack@wobblini.net

Hi –

···

On Wed, 10 Dec 2003, Robert Klemme wrote:

“David A. Black” dblack@wobblini.net schrieb im Newsbeitrag
news:Pine.LNX.4.44.0312090906230.13718-100000@wobblini.net

Actually I feel that “self.instance_eval” should be
a no-op, since what it conveys (absent the magic) is: execute what
follows, setting self to what it already is.

Not exactly, it overrides any setting of self in the environment that
cometh with the block / closure. IOW, the closure’s env is modified for
this call so that “self” points to the invoking “self” and not the “self”
at the time of definition. So it is not really a noop.

I know it isn’t. I said I feel that it (self.instance_eval) should
be
a no-op.

Still mulling over Guy’s class_eval thing… :slight_smile:

David


David A. Black
dblack@wobblini.net

Hi –

[ interesting Lisp remarks which I fully intend to go back ]
[ and look at again :slight_smile: ]

Proc objects are the same way. Code + context. #call works like a
normal closure (same as calling the method in Scheme), while #?_eval
replaces some of the context.

At the risk of repeating myself: yeah, but that’s the part I don’t
like :slight_smile: Actually I think it is, for me, a lexical-scope thing.
Guy’s example, or something like:

obj.instance_eval { stuff }

where it’s all visible and lexically scoped together, doesn’t bug me
at all. It only starts feeling “trick”-like when the fact that the
block is going to be instance_eval’d in obj’s self context isn’t
manifest.

OK, trying to zero in on this, here’s a case. What if I want to use
a locally defined method in a block? For example:

def x; [1,2,3]; end
obj.some_method { x } # I want the block to evaluate to [1,2,3]
# if called or yielded to. That’s what I
# mean by ‘x’.

Now, if #some_method’s class happens to have an #x method,
#some_method can sort of hijack my call to #x. But I shouldn’t know
that or have to know it. If my “x” is going to be eval’d as a method
call other than the one I thought it was, I want to be in on the deal
and send it as an eval string.

It reminds me a bit of things that depend on coordination (and
therefore coupling) of local variable names between methods. It also
seems to be predicated on a somewhat arbitrary variable/method-call
split; if I’d done x=[1,2,3] above, instead of defining #x, ‘x’
wouldn’t be vulnerable.

In some sense it is. self.instance_eval is a no-op with respect to
Strings passed in. self.instance_eval is a no-op as long as you’re
just talking about a collection of code. It’s only not a no-op when
you take context into account.

(I think that makes it a sometimes-op :slight_smile:

[…]

I may have passed over that thread… I’ll look again.

The subject at the top of the thread was: Re: Controlled Block
Variables You actually replied to my first post about it basically
saying you didn’t like the idea of blocks-as-just-code. :slight_smile: Then
nothing after that so maybe you didn’t read anything else.

Yeah, I looked up the thread and found that I had participated in it
and forgotten. Old age, you know :slight_smile:

David

···

On Wed, 10 Dec 2003, Dan Doel wrote:


David A. Black
dblack@wobblini.net

Uh oh. I sense the beginning of the end :slight_smile: What don't I (appear to)
like about it?

svg% cat b.rb
#!/usr/bin/ruby

class A
   def self.n
      puts "A::n"
   end
end

def n
   puts "Object#n"
end

A.class_eval { n }
svg%

svg% b.rb
svg%

Guy Decoux

···

A::n

[D. Black, ruthlessly snipped:]

obj.instance_eval { stuff }

where it’s all visible and lexically scoped together, doesn’t bug me at
all. It only starts feeling “trick”-like when the fact that the block
is going to be instance_eval’d in obj’s self context isn’t
manifest.

I agree with everything you wrote, David. But taking a step back, I’m
inclined to judge that when you pass a block to a method, you have some
idea what the method will do to it. “Iterator” and “transactional” blocks
are pretty obvious. “Event-handlers” are pretty cool, too, and it’s easy
to understand what they do (execute the block later).

If a method is going to instance-eval or class-eval a block, then it’s an
unusual method (not in a common class of methods). Eval-ing is good for
low-level infrastructure implementation more so than run-of-the-mill data
processing. Methods that use ?_eval are likely to be “special”,
implementing unusual or tricky (but useful) concepts. Their documentation
should therefore indicate what the user of the method can expect.

Gavin

Hi –

···

On Wed, 10 Dec 2003, ts wrote:

Uh oh. I sense the beginning of the end :slight_smile: What don’t I (appear to)
like about it?

svg% cat b.rb
#!/usr/bin/ruby

class A
def self.n
puts “A::n”
end
end

def n
puts “Object#n”
end

A.class_eval { n }
svg%

svg% b.rb
A::n
svg%

I think what bothers me about the other case, where a method grabs a
block and instance_eval’s it, is the sense that the block might have
“wanted” to refer to a different n (or whatever). When it’s all
visible as above, there’s no such danger, and therefore, to me, no
“magic” aspect.

David


David A. Black
dblack@wobblini.net