Adjusting the Scope of Blocks

M

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
}

Thanks in advance.

Mark Cox
 
G

Gavin Sinclair

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
 
R

Robert Klemme

Gavin Sinclair said:
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
 
M

Mark Cox

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. :)

Mark.
 
R

Robert Klemme

Mark Cox said:
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. :)

You really are. Shame on you! :)

robert
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top