Adjusting the Scope of Blocks

Discussion in 'Ruby' started by Mark Cox, Dec 9, 2003.

  1. Mark Cox

    Mark Cox Guest

    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
     
    Mark Cox, Dec 9, 2003
    #1
    1. Advertising

  2. > 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, Dec 9, 2003
    #2
    1. Advertising

  3. "Gavin Sinclair" <> schrieb im Newsbeitrag
    news:...
    > > 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
     
    Robert Klemme, Dec 9, 2003
    #3
  4. Mark Cox

    Mark Cox Guest

    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:...
    >> > 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
     
    Mark Cox, Dec 10, 2003
    #4
  5. "Mark Cox" <> schrieb im Newsbeitrag
    news:...
    > 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

    >
    > Mark.
    >
    > Robert Klemme wrote:
    >
    > >
    > > "Gavin Sinclair" <> schrieb im Newsbeitrag
    > > news:...
    > >> > 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

    >
     
    Robert Klemme, Dec 10, 2003
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Arjen
    Replies:
    3
    Views:
    461
    Scott Allen
    Feb 27, 2005
  2. Arved Sandstrom

    Blocks for scope control

    Arved Sandstrom, Jan 15, 2012, in forum: Java
    Replies:
    32
    Views:
    783
    Arne Vajhøj
    Feb 7, 2012
  3. Steve Cooper
    Replies:
    2
    Views:
    138
    Kenta MURATA
    Jan 18, 2004
  4. matt
    Replies:
    1
    Views:
    287
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    277
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page