[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

remove or delete variable

Daniel Schüle

1/15/2006 3:29:00 AM

Hello all,

is it possible to delete a variable

for example

class X
def foo(k);@f=k;end
def bar; end # how to remove @f?
def f;@f;end
end

x=X.new
x.foo(1) # create @f
x.f => 1 # it's there
x.bar # delete it
x.f => # Error

is it possible?

and same question to local variables

Regards, Daniel

5 Answers

Ross Bamford

1/15/2006 12:50:00 PM

0

On Sun, 15 Jan 2006 03:28:34 -0000, Schüle Daniel
<uval@rz.uni-karlsruhe.de> wrote:

> Hello all,
>
> is it possible to delete a variable
>
> for example
>
> class X
> def foo(k);@f=k;end
> def bar; end # how to remove @f?
def bar; remove_instance_variable '@f'; end # <-- Change to this
> def f;@f;end
> end
>

Is that what you're after?:

x = X.new
# => #<X:0xb7e6a280>
x.foo(1)
# => 1
x.f
# => 1
x.bar
# => 1
x.f
# => nil

I think it's a different matter with local variables, I don't know of a
way to remove them (you can just set them nil, of course, but it doesn't
actually remove them). Someone else is sure to have a definitive answer to
that.

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Robert Klemme

1/15/2006 1:02:00 PM

0

Schüle Daniel <uval@rz.uni-karlsruhe.de> wrote:
> Hello all,
>
> is it possible to delete a variable
>
> for example
>
> class X
> def foo(k);@f=k;end
> def bar; end # how to remove @f?
> def f;@f;end
> end
>
> x=X.new
> x.foo(1) # create @f
> x.f => 1 # it's there
> x.bar # delete it
> x.f => # Error
>
> is it possible?
>
> and same question to local variables
>
> Regards, Daniel

Not as far as I know. What do you need that for?

The usual approach is to set something to nil. If you need similar behavior
you can either use a hash and test for key presence or use OpenStruct -
although that won't raise an exception:

>> require 'ostruct'
=> true
>> o=OpenStruct.new
=> #<OpenStruct>
>> o.foo = 1
=> 1
>> o
=> #<OpenStruct foo=1>
>> o.respond_to? :foo
=> true
>> o.delete_field :foo
=> 1
>> o
=> #<OpenStruct>
>> o.foo
=> nil

Of course you can create your own class.

class ChangingFields
def method_missing(s,*a,&b)
case s.to_s
when /^(.*)=$/
field = $1
class << self;self;end.class_eval do
attr_accessor field
end
send(s,*a,&b)
else
super
end
end

def remove_field(field)
class << self;self;end.class_eval do
remove_method( field )
remove_method( "#{field}=" )
end
instance_variable_set("@#{field}", nil)
end
end

irb(main):052:0> c=ChangingFields.new
=> #<ChangingFields:0x101d0b88>
irb(main):053:0> c.foo = 1
=> 1
irb(main):054:0> c
=> #<ChangingFields:0x101d0b88 @foo=1>
irb(main):055:0> c.foo
=> 1
irb(main):056:0> c.remove_field :foo
=> nil
irb(main):057:0> c
=> #<ChangingFields:0x101d0b88 @foo=nil>
irb(main):058:0> c.foo
NoMethodError: undefined method `foo' for #<ChangingFields:0x101d0b88
@foo=nil>
from (irb):37:in `method_missing'
from (irb):58
from (null):0


Kind regards

robert

Todd

1/15/2006 6:12:00 PM

0


Robert Klemme wrote:
> Schüle Daniel <uval@rz.uni-karlsruhe.de> wrote:
> > Hello all,
> >
> > is it possible to delete a variable

[snip]

> Not as far as I know. What do you need that for?

Personally, I wouldn't mind seeing a way to force garbage collection of
a specific object. I seem to recall, though, someone saying it wasn't
possible, or that it wasn't necessary.

Todd

Daniel Schüle

1/15/2006 11:58:00 PM

0

[...]

> Not as far as I know. What do you need that for?

I am learning Ruby and was trying to explore if there exist
something Pythonlike

>>> class X:
.... pass
....
>>> x=X()
>>> x.foo = 1
>>> x.foo
1
>>> del x.foo
>>> x.foo
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: X instance has no attribute 'foo'
>>>
>>> x
<__main__.X instance at 0x403e3bec>
>>> del x
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'x' is not defined
>>>


> Of course you can create your own class.
>
> class ChangingFields
> def method_missing(s,*a,&b)
> case s.to_s
> when /^(.*)=$/
> field = $1
> class << self;self;end.class_eval do
> attr_accessor field
> end
> send(s,*a,&b)
> else
> super
> end
> end
>
> def remove_field(field)
> class << self;self;end.class_eval do
> remove_method( field )
> remove_method( "#{field}=" )
> end
> instance_variable_set("@#{field}", nil)
> end
> end

metaprogramming is still one of my weak points

why do you use
class << self;self;end.class_eval do ... end
and not just
ChangingFields.class_eval do ... end


> irb(main):052:0> c=ChangingFields.new
> => #<ChangingFields:0x101d0b88>
> irb(main):053:0> c.foo = 1
> => 1
> irb(main):054:0> c
> => #<ChangingFields:0x101d0b88 @foo=1>
> irb(main):055:0> c.foo
> => 1
> irb(main):056:0> c.remove_field :foo
> => nil
> irb(main):057:0> c
> => #<ChangingFields:0x101d0b88 @foo=nil>
> irb(main):058:0> c.foo
> NoMethodError: undefined method `foo' for #<ChangingFields:0x101d0b88
> @foo=nil>
> from (irb):37:in `method_missing'
> from (irb):58
> from (null):0

thx for this example, I will try to digest it :)

Regards, Daniel

Robert Klemme

1/18/2006 10:53:00 PM

0

Schüle Daniel <uval@rz.uni-karlsruhe.de> wrote:
> [...]
>
>> Not as far as I know. What do you need that for?
>
> I am learning Ruby and was trying to explore if there exist
> something Pythonlike
>
>>>> class X:
> ... pass
> ...
>>>> x=X()
>>>> x.foo = 1
>>>> x.foo
> 1
>>>> del x.foo
>>>> x.foo
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> AttributeError: X instance has no attribute 'foo'
>>>>
>>>> x
> <__main__.X instance at 0x403e3bec>
>>>> del x
>>>> x
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> NameError: name 'x' is not defined
>>>>

Usually it's sufficient to set the attribute value to nil. You'll soon
learn that the attribute had the wrong value - at that point when someone
invokes a method on nil that is not defined for NilClass. Personally I
never felt the need to actually take attribute accessors away from an
instance.

>> Of course you can create your own class.
>>
>> class ChangingFields
>> def method_missing(s,*a,&b)
>> case s.to_s
>> when /^(.*)=$/
>> field = $1
>> class << self;self;end.class_eval do
>> attr_accessor field
>> end
>> send(s,*a,&b)
>> else
>> super
>> end
>> end
>>
>> def remove_field(field)
>> class << self;self;end.class_eval do
>> remove_method( field )
>> remove_method( "#{field}=" )
>> end
>> instance_variable_set("@#{field}", nil)
>> end
>> end
>
> metaprogramming is still one of my weak points

It's one of the areas that takes a little longer to feel at home with - at
least longer than the usual OO stuff.

> why do you use
> class << self;self;end.class_eval do ... end
> and not just
> ChangingFields.class_eval do ... end

Because if I understood you correctly you want to add and remove fields on
an per instance basis. If you do it with the class object, you'll define
instance methods for all instances (effective immediately).

>> irb(main):052:0> c=ChangingFields.new
>> => #<ChangingFields:0x101d0b88>
>> irb(main):053:0> c.foo = 1
>> => 1
>> irb(main):054:0> c
>> => #<ChangingFields:0x101d0b88 @foo=1>
>> irb(main):055:0> c.foo
>> => 1
>> irb(main):056:0> c.remove_field :foo
>> => nil
>> irb(main):057:0> c
>> => #<ChangingFields:0x101d0b88 @foo=nil>
>> irb(main):058:0> c.foo
>> NoMethodError: undefined method `foo' for #<ChangingFields:0x101d0b88
>> @foo=nil>
>> from (irb):37:in `method_missing'
>> from (irb):58
>> from (null):0
>
> thx for this example, I will try to digest it :)

You're welcome! While I think about it, a better approach might be to
define explicit methods that create and remove attributes on an per instance
basis:

class Changing
def def_attr(sym)
class<<self;self;end.class_eval do
attr_accessor sym
end
end

def undef_attr(sym)
instance_variable_set("@#{sym}", nil)
class<<self;self;end.class_eval "undef #{sym};undef #{sym}="
end
end

>> c=Changing.new
=> #<Changing:0x1019d390>
>> c.foo
NoMethodError: undefined method `foo' for #<Changing:0x1019d390>
from (irb):73
from :0
>> c.def_attr :foo
=> nil
>> c.foo
=> nil
>> c.foo=10
=> 10
>> c.foo
=> 10
>> c.undef_attr :foo
=> nil
>> c.foo
NoMethodError: undefined method `foo' for #<Changing:0x1019d390 @foo=nil>
from (irb):79

Kind regards

robert