From: Mark Cox Date: 2003-12-10T11:22:05+09:00 Subject: Re: Adjusting the Scope of Blocks 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. Robert Klemme wrote: > > "Gavin Sinclair" 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