Hi,
Creating an attribute reader and not initializing the attribute (either
with @foo= or with self.foo=) is a bug. The user should never see this
warning except for buggy code.
I thought it is needed just because
@foo ||=
trick cannot be done for attributes without causing warning.
???
batsman@tux-chan:/tmp$ irb --simple-prompt
/usr/lib/ruby/1.6/irb/context.rb:112: warning: method redefined; discarding old irb_name
/usr/lib/ruby/1.6/irb/context.rb:176: warning: method redefined; discarding old math_mode=
/usr/lib/ruby/1.6/irb/context.rb:188: warning: method redefined; discarding old use_readline=
/usr/lib/ruby/1.6/irb/context.rb:177: warning: instance variable @math_mode not initialized
/usr/lib/ruby/1.6/irb/context.rb:151: warning: instance variable @use_tracer not initialized
class A; def foo; @foo ||= ; end; end
=> nil
A.new.foo
=>
If you mean that attr_* won’t work with default values, we can use
something like the following:
batsman@tux-chan:/tmp$ set | grep RUBYOPT
RUBYOPT=-w
batsman@tux-chan:/tmp$ expand -t 2 z.rb
module AttrWithDefault
def attr_reader_with_default(sym, val)
instance_eval <<-EOF
class << self
attr_accessor “#{sym.to_s}”.intern
attr_reader :symlist
end
@symlist ||=
@symlist.push( [self, “#{sym}”] )
EOF
meth = self.method “#{sym.to_s}=”.intern
meth.call( val )
module_eval <<-EOF
def #{sym.to_s}
@#{sym.to_s} ||= self.class._#{sym.to_s}_
end
EOF
if self.singleton_methods.grep("inherited") == []
class << self
def inherited sub
ancestors.each do |klass|
begin
assoc = klass.__symlist__
assoc.each do |x|
#puts "Redefining #{x[1]} from #{sub} using #{x[0]}._#{x[1]}_"
sub.module_eval <<-EOF
def #{x[1]}
@#{x[1]} ||= #{x[0]}._#{x[1]}_
end
EOF
end
rescue NameError
end
end
end
end
end
end
end
class A
extend AttrWithDefault
attr_reader_with_default :foo,
attr_reader_with_default :bar, ‘test’
def inspect
str = “#{self.class}:”
instance_variables.each do |iv|
str << " #{iv} => "
str << instance_eval(“#{iv}”).inspect
end
str
end
end
a = A.new
p a
a.foo
p a
class B < A
attr_reader_with_default :bar2, ‘bla’
end
class C < B
end
b = B.new
p b
b.foo
b.bar
p b
c = C.new
p c
c.foo
c.bar
c.bar2
p c
batsman@tux-chan:/tmp$ ruby z.rb
A:
B:
B: @bar => “test” @foo =>
C:
C: @bar => “test” @bar2 => “bla” @foo =>
I am not sure about what default value to take when several are
specified at different points along the inheritance chain.
···
On Wed, Feb 19, 2003 at 05:08:19PM +0900, Yukihiro Matsumoto wrote:
In message “Re: How to test for existence of instance variable?” > on 03/02/19, Paul Brannan pbrannan@atdesk.com writes:
A: @foo =>
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Sigh. I like to think it’s just the Linux people who want to be on
the “leading edge” so bad they walk right off the precipice.
– Craig E. Groeschel