remove or delete variable

S

Schüle Daniel

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
 
R

Ross Bamford

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.
 
R

Robert Klemme

Schüle Daniel said:
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:
=> 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
 
T

Todd

Robert said:
Schüle Daniel said:
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
 
S

Schüle Daniel

[...]
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
.... pass
....Traceback (most recent call last):
Traceback (most recent call last):
File said:
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
 
R

Robert Klemme

Schüle Daniel said:
[...]
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
... pass
...Traceback (most recent call last):
Traceback (most recent call last):

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.
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).
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
NoMethodError: undefined method `foo' for #<Changing:0x1019d390>
from (irb):73
from :0NoMethodError: undefined method `foo' for #<Changing:0x1019d390 @foo=nil>
from (irb):79

Kind regards

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,795
Messages
2,569,644
Members
45,359
Latest member
1854578

Latest Threads

Top