Static variable; behaviour in ruby?

Any idea how to create or simulate a static variable in ruby?

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm trying to do an instance_eval on a string containing a method such as
   do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called several
times, but I only want the state intialized the first time the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Maybe there's another way to do this?

        Thank you
        Hugh

I advise that you state your basic problem, as this seems to be a
problem with an ugly workaround. You can probably restructure your
problem such that this is no longer needed.

Brian

···

On 16/11/05, Hugh Sasse <hgs@dmu.ac.uk> wrote:

Any idea how to create or simulate a static variable in ruby?

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm trying to do an instance_eval on a string containing a method such as
   do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called several
times, but I only want the state intialized the first time the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Maybe there's another way to do this?

        Thank you
        Hugh

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Hugh Sasse schrieb:

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.

and

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Isn't this a contradiction?

When should the state appear and when should it disappear? What should be the scope of the state?

Regards,
Pit

Any idea how to create or simulate a static variable in ruby?

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm trying to do an instance_eval on a string containing a method such as
  do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called several
times, but I only want the state intialized the first time the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

   harp:~ > cat a.rb
   def do_this_factory x, y, z, &block
     state = rand # do something with x, y, z
     lambda{ block[x, y, z] if state < 0.42 }
   end

   a = do_this_factory 'x','y','z' do |x,y,z| p [x,y,z] end
   a.call

   harp:~ > ruby a.rb

   harp:~ > ruby a.rb

   harp:~ > ruby a.rb
   ["x", "y", "z"]

   harp:~ > ruby a.rb

   harp:~ > ruby a.rb
   ["x", "y", "z"]

   harp:~ > ruby a.rb
   ["x", "y", "z"]

Maybe there's another way to do this?

write it in assembler :wink:

-a

···

On Wed, 16 Nov 2005, Hugh Sasse wrote:
--

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

===============================================================================

Hugh Sasse wrote:

Any idea how to create or simulate a static variable in ruby?

I completely agree to Brian's comment.

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm not sure I understand you correctly here. Why don't you just create
an instance that holds this state plus whatever is needed and implement
your behavior in a method of that class? You can control the number of
scopes by the nuber of created instances.

Also, IMHO Pit has a valid point with his remark about a contradiction.

I'm trying to do an instance_eval on a string containing a method
   such as do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called
several times, but I only want the state intialized the first time
the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Maybe there's another way to do this?

Did you consider using a Thread local stack for this (as I conclude from
your latest posting nesting is possible)?

Kind regards

    robert

> Any idea how to create or simulate a static variable in ruby?
>
> I want to create a variable to hold state between calls of a method,
> but have the state disappear when the method goes out of scope.
> I could create it in some external object but then I'd need to query
> the scoping rules, and know where i was.
>
> I'm trying to do an instance_eval on a string containing a method such as
> do_this x,y,z {block}
> and I want to evaluate the block, or not, as a function of some
> state against which x,y,z are compared. The code will be called several
> times, but I only want the state intialized the first time the scope
> is entered.
>
> And, just to make matters worse, there could be several independent
> calls to this method within the scope, each with its own separate
> state.
>
> Maybe there's another way to do this?
>
> Thank you
> Hugh
>
>

I advise that you state your basic problem, as this seems to be a
problem with an ugly workaround. You can probably restructure your
problem such that this is no longer needed.

I thought the paragraph about instance_eval explained it :-).

Essentially, I have become fed up with lousy diagnostics from sed,
and have been trying to re-implement (enough of) it in Ruby, so I
hae some chance of getting the code to work. Thus I'd use code like:

   within 10, 30 {
     sub(/this/, 'that')
     sub(/thingy/, 'the other')
     # Example of munging something akin to C comments
     within /^\s+\/\*/, /\*\/\s*$/ {
       rot13 # or something
     }
   }

So I need to keep track of which patterns have matched, and clear
them when the scope (surrounding block) is gone.

Brian

        Hugh

···

On Wed, 16 Nov 2005, Brian Schröder wrote:

On 16/11/05, Hugh Sasse <hgs@dmu.ac.uk> wrote:

Hugh Sasse wrote:
> Any idea how to create or simulate a static variable in ruby?

I completely agree to Brian's comment.

> I want to create a variable to hold state between calls of a method,
> but have the state disappear when the method goes out of scope.
> I could create it in some external object but then I'd need to query
> the scoping rules, and know where i was.

I'm not sure I understand you correctly here. Why don't you just create
an instance that holds this state plus whatever is needed and implement
your behavior in a method of that class? You can control the number of

Because I can't see how to call it into being correctly. If I need
to know "when this method was called the first time" to do this,
then I need something with the same properties as a static variable,
in order to implement a thing with the same properties as a static
variable.

scopes by the nuber of created instances.

But I need to know when to create them for the string I'm
evaluating, rather than when to call on existing ones in that string.

Also, IMHO Pit has a valid point with his remark about a contradiction.

In ruby you can have several flip-flop expressions in the same
context...

> I'm trying to do an instance_eval on a string containing a method
> such as do_this x,y,z {block}
> and I want to evaluate the block, or not, as a function of some
> state against which x,y,z are compared. The code will be called
> several times, but I only want the state intialized the first time
> the scope
> is entered.
>
> And, just to make matters worse, there could be several independent
> calls to this method within the scope, each with its own separate
> state.
>
> Maybe there's another way to do this?

Did you consider using a Thread local stack for this (as I conclude from
your latest posting nesting is possible)?

There is no concurrency in the thing at the moment, so I'm not sure
how to make use of that. Maybe it is a design pattern I've missed.

I'm beginning to think it is nontrivial, and will probably to to use
gawk to avoid sed in this case.

Kind regards

    robert

        Thank you,
        Hugh

···

On Wed, 16 Nov 2005, Robert Klemme wrote:

> Any idea how to create or simulate a static variable in ruby?

        [...]

  harp:~ > cat a.rb
  def do_this_factory x, y, z, &block
    state = rand # do something with x, y, z
    lambda{ block[x, y, z] if state < 0.42 }
  end

  a = do_this_factory 'x','y','z' do |x,y,z| p [x,y,z] end
  a.call
  harp:~ > ruby a.rb

  harp:~ > ruby a.rb
  ["x", "y", "z"]

        [etc]

Maybe something like
    def my_method x, y, z, &block
      state = rand # do something with x, y, z
      alias :old_my_method, :my_method
      define_method(:my_method)(x,y,z, &block)
        lambda{ block[x, y, z] if state < 0.42 }.call
      end
    end

might do the trick, then? The state would get carried around with
the closure in subesequent calls to the same method? Except having
sevaral calls in the same block would be treated the same as severl
calls to the same method, rather than the way sed treats
/this/,/that/{ statements}, each heing independent, runnin for each
line of the input.

> Maybe there's another way to do this?

write it in assembler :wink:

:slight_smile:

        Hugh

···

On Wed, 16 Nov 2005, Ara.T.Howard wrote:

On Wed, 16 Nov 2005, Hugh Sasse wrote:

Hugh Sasse wrote:

···

On Wed, 16 Nov 2005, Robert Klemme wrote:

Hugh Sasse wrote:

Any idea how to create or simulate a static variable in ruby?

I completely agree to Brian's comment.

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm not sure I understand you correctly here. Why don't you just
create an instance that holds this state plus whatever is needed and
implement your behavior in a method of that class? You can control
the number of

Because I can't see how to call it into being correctly. If I need
to know "when this method was called the first time" to do this,
then I need something with the same properties as a static variable,
in order to implement a thing with the same properties as a static
variable.

scopes by the nuber of created instances.

But I need to know when to create them for the string I'm
evaluating, rather than when to call on existing ones in that string.

Also, IMHO Pit has a valid point with his remark about a
contradiction.

In ruby you can have several flip-flop expressions in the same
context...

I'm trying to do an instance_eval on a string containing a method
   such as do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called
several times, but I only want the state intialized the first time
the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Maybe there's another way to do this?

Did you consider using a Thread local stack for this (as I conclude
from your latest posting nesting is possible)?

There is no concurrency in the thing at the moment, so I'm not sure
how to make use of that. Maybe it is a design pattern I've missed.

I'm beginning to think it is nontrivial, and will probably to to use
gawk to avoid sed in this case.

I'm not yet convinced that it's actually so complicated. Please see my
other posting.

    robert

Hugh Sasse wrote:

Any idea how to create or simulate a static variable in ruby?

I want to create a variable to hold state between calls of a method,
but have the state disappear when the method goes out of scope.
I could create it in some external object but then I'd need to query
the scoping rules, and know where i was.

I'm trying to do an instance_eval on a string containing a method
   such as do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called
several times, but I only want the state intialized the first time
the scope
is entered.

And, just to make matters worse, there could be several independent
calls to this method within the scope, each with its own separate
state.

Maybe there's another way to do this?

        Thank you
        Hugh

I advise that you state your basic problem, as this seems to be a
problem with an ugly workaround. You can probably restructure your
problem such that this is no longer needed.

I thought the paragraph about instance_eval explained it :-).

Essentially, I have become fed up with lousy diagnostics from sed,
and have been trying to re-implement (enough of) it in Ruby, so I
hae some chance of getting the code to work. Thus I'd use code like:

   within 10, 30 {
     sub(/this/, 'that')
     sub(/thingy/, 'the other')
     # Example of munging something akin to C comments
     within /^\s+\/\*/, /\*\/\s*$/ {
       rot13 # or something
     }
   }

So I need to keep track of which patterns have matched, and clear
them when the scope (surrounding block) is gone.

Let's see whether I understand this correctly: you want your method
"within" to create something that can be later thrown against the current
line of the input and execute the given block only if the condition
matches? Wouldn't it be easier to just call within for each line of the
input?

Kind regards

    robert

···

On Wed, 16 Nov 2005, Brian Schröder wrote:

On 16/11/05, Hugh Sasse <hgs@dmu.ac.uk> wrote:

Maybe something like
   def my_method x, y, z, &block
     state = rand # do something with x, y, z
     alias :old_my_method, :my_method
     define_method(:my_method)(x,y,z, &block)
       lambda{ block[x, y, z] if state < 0.42 }.call
     end
   end

but the second time my_method is called you'll clobber old_my_method - is that
what you want? plus it only works once because the first call to my_method
will define it in such a way that it never sets of state again - it's
clobbered by the define_method/lambda bit...

might do the trick, then? The state would get carried around with the
closure in subesequent calls to the same method? Except having sevaral
calls in the same block would be treated the same as severl calls to the
same method, rather than the way sed treats /this/,/that/{ statements}, each
heing independent, runnin for each line of the input.

i really don't quite get what you are after. but from what i'm reading it
looks alot like you would be better off doing something like this

   class Line
     def initialize x, y, z, &statements
       @state = rand
       @x, @y, @z = x, y, z
       @statements = statements
     end
     def my_method
       @statements[@x, @y, @z] if @state < 0.42
     end
   end

put another way - a static variable can be emulated as an instance variable of
an object. you can have multiple copies by having multiple instances. the
initialize methods makes sure it's only called once.

this might be easier?

-a

···

On Thu, 17 Nov 2005, Hugh Sasse wrote:
--

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

===============================================================================

Hugh Sasse wrote:
>
>>> Any idea how to create or simulate a static variable in ruby?
>>>
>>> I want to create a variable to hold state between calls of a method,
>>> but have the state disappear when the method goes out of scope.
>>> I could create it in some external object but then I'd need to query
>>> the scoping rules, and know where i was.
>>>
>>> I'm trying to do an instance_eval on a string containing a method
>>> such as do_this x,y,z {block}
>>> and I want to evaluate the block, or not, as a function of some
>>> state against which x,y,z are compared. The code will be called
>>> several times, but I only want the state intialized the first time
>>> the scope
>>> is entered.
>>>
>>> And, just to make matters worse, there could be several independent
>>> calls to this method within the scope, each with its own separate
>>> state.
>>>
>>> Maybe there's another way to do this?
>>>
>>> Thank you
>>> Hugh
>>>
>>>
>>
>> I advise that you state your basic problem, as this seems to be a
>> problem with an ugly workaround. You can probably restructure your
>> problem such that this is no longer needed.
>
> I thought the paragraph about instance_eval explained it :-).
>
> Essentially, I have become fed up with lousy diagnostics from sed,
> and have been trying to re-implement (enough of) it in Ruby, so I
> hae some chance of getting the code to work. Thus I'd use code like:
>
> within 10, 30 {
> sub(/this/, 'that')
> sub(/thingy/, 'the other')
> # Example of munging something akin to C comments
> within /^\s+\/\*/, /\*\/\s*$/ {
> rot13 # or something
> }
> }
>
> So I need to keep track of which patterns have matched, and clear
> them when the scope (surrounding block) is gone.

Let's see whether I understand this correctly: you want your method
"within" to create something that can be later thrown against the current
line of the input and execute the given block only if the condition
matches? Wouldn't it be easier to just call within for each line of the
input?

all the statements in the input language which I'm processing with
instance_eval (for now) would be called for each line of the input.
So when each one that must hold state is called for the first time
it must clear the state, for future calls to that function on that
source line, but later input lines, it must not "cold start" the
state.

For within(), I'm trying to model sed's '/this/, /that/ { do_this}'
And I could have several withins in the same chunk of input
language.

Kind regards

    robert

        Thank you,
        Hugh

···

On Thu, 17 Nov 2005, Robert Klemme wrote:

> On Wed, 16 Nov 2005, Brian Schröder wrote:
>> On 16/11/05, Hugh Sasse <hgs@dmu.ac.uk> wrote:

Hugh Sasse wrote:

Hugh Sasse wrote:

Any idea how to create or simulate a static variable in ruby?

I want to create a variable to hold state between calls of a
method, but have the state disappear when the method goes out of
scope.
I could create it in some external object but then I'd need to
query the scoping rules, and know where i was.

I'm trying to do an instance_eval on a string containing a method
   such as do_this x,y,z {block}
and I want to evaluate the block, or not, as a function of some
state against which x,y,z are compared. The code will be called
several times, but I only want the state intialized the first time
the scope
is entered.

And, just to make matters worse, there could be several
independent calls to this method within the scope, each with its
own separate state.

Maybe there's another way to do this?

        Thank you
        Hugh

I advise that you state your basic problem, as this seems to be a
problem with an ugly workaround. You can probably restructure your
problem such that this is no longer needed.

I thought the paragraph about instance_eval explained it :-).

Essentially, I have become fed up with lousy diagnostics from sed,
and have been trying to re-implement (enough of) it in Ruby, so I
hae some chance of getting the code to work. Thus I'd use code like:

   within 10, 30 {
     sub(/this/, 'that')
     sub(/thingy/, 'the other')
     # Example of munging something akin to C comments
     within /^\s+\/\*/, /\*\/\s*$/ {
       rot13 # or something
     }
   }

So I need to keep track of which patterns have matched, and clear
them when the scope (surrounding block) is gone.

Let's see whether I understand this correctly: you want your method
"within" to create something that can be later thrown against the
current line of the input and execute the given block only if the
condition matches? Wouldn't it be easier to just call within for
each line of the input?

all the statements in the input language which I'm processing with
instance_eval (for now) would be called for each line of the input.
So when each one that must hold state is called for the first time
it must clear the state, for future calls to that function on that
source line, but later input lines, it must not "cold start" the
state.

For within(), I'm trying to model sed's '/this/, /that/ { do_this}'
And I could have several withins in the same chunk of input
language.

I think I start getting a better understanding of your issue. How about:

def within(*a, &b)
  my_state = (Thread.current[:within] || = {})[a] ||= WithinState.new(a,b)
  my_state.feed(current_line)
end

If you want to make this safe against multiple invocations with similar
parameters you might use another identifying thing (possibly invoking
caller to determine source code location).

Instead of the thread local you could also use a global but IMHO this is
cleaner.

HTH

Kind regards

    robert

···

On Thu, 17 Nov 2005, Robert Klemme wrote:

On Wed, 16 Nov 2005, Brian Schröder wrote:

On 16/11/05, Hugh Sasse <hgs@dmu.ac.uk> wrote:

Hugh Sasse wrote:
>
>> Let's see whether I understand this correctly: you want your method
>> "within" to create something that can be later thrown against the
>> current line of the input and execute the given block only if the
>> condition matches? Wouldn't it be easier to just call within for
>> each line of the input?
>
> all the statements in the input language which I'm processing with
> instance_eval (for now) would be called for each line of the input.
> So when each one that must hold state is called for the first time
> it must clear the state, for future calls to that function on that
> source line, but later input lines, it must not "cold start" the
> state.

My use of "input" for supplied source code *and* data to process was
less than helpful. Sorry about that.

>
> For within(), I'm trying to model sed's '/this/, /that/ { do_this}'
> And I could have several withins in the same chunk of input
> language.

I think I start getting a better understanding of your issue. How about:

def within(*a, &b)
  my_state = (Thread.current[:within] || = {})[a] ||= WithinState.new(a,b)
  my_state.feed(current_line)
end

If you want to make this safe against multiple invocations with similar
parameters you might use another identifying thing (possibly invoking
caller to determine source code location).

Yes, I was looking for that: I'd forgotten I could use caller in
something eval'd.

Making it thread local means it outlives the scope of def and is not
in the normal global namespace. That's a neat idea.
I think this will do everything I want....

Instead of the thread local you could also use a global but IMHO this is
cleaner.

HTH

Kind regards

    robert

        Thank you,
        Hugh

···

On Thu, 17 Nov 2005, Robert Klemme wrote:

> On Thu, 17 Nov 2005, Robert Klemme wrote:

Hugh Sasse wrote:

Hugh Sasse wrote:

Let's see whether I understand this correctly: you want your method
"within" to create something that can be later thrown against the
current line of the input and execute the given block only if the
condition matches? Wouldn't it be easier to just call within for
each line of the input?

all the statements in the input language which I'm processing with
instance_eval (for now) would be called for each line of the input.
So when each one that must hold state is called for the first time
it must clear the state, for future calls to that function on that
source line, but later input lines, it must not "cold start" the
state.

My use of "input" for supplied source code *and* data to process was
less than helpful. Sorry about that.

For within(), I'm trying to model sed's '/this/, /that/ { do_this}'
And I could have several withins in the same chunk of input
language.

I think I start getting a better understanding of your issue. How
about:

def within(*a, &b)
  my_state = (Thread.current[:within] || = {})[a] ||=
  WithinState.new(a,b) my_state.feed(current_line)
end

If you want to make this safe against multiple invocations with
similar parameters you might use another identifying thing (possibly
invoking caller to determine source code location).

Yes, I was looking for that: I'd forgotten I could use caller in
something eval'd.

Making it thread local means it outlives the scope of def and is not
in the normal global namespace. That's a neat idea.

And it's thread safe and automatically GC'ed on thread termination. :slight_smile:

I think this will do everything I want....

Cool! Glad I could help.

Cheers

    robert

···

On Thu, 17 Nov 2005, Robert Klemme wrote:

On Thu, 17 Nov 2005, Robert Klemme wrote: