My attr_accessor


#1

I tried to

class Foo
attr_accessor :bar1, :bar2

def initialize( &bloc )
instance_eval( &bloc )
end
end

and then

f = Foo.new {
bar1 = 12345
bar2 = 44444
}

but this doesn’t work
unless you write @bar1=12345 in the block, as
Ruby does not consider bar1= a method call but an assignment.

Here’s my solution. Any comments?

#--------------------------------
module MyAccessor
def my_attr (nou, defval=nil)
class_eval "
def #{nou} (s=nil)
@#{nou} = s || @#{nou} || ‘#{defval}’
end
"
end # def my_attr
end # module

#--------------------------------
class Foo

extend MyAccessor

my_attr(:title, “default title”)
my_attr(:height, 100)
my_attr(:color, ‘black’)

def initialize( &bloc )
instance_eval( &bloc )
end # def

def show
puts “attributes ----------”
puts “title=”+ title.to_s
puts “color=”+ color.to_s
puts “height=”+ height.to_s
end

end

#----------------------------------
#----------------------------------
fo = Foo.new() {
color “red”
height 50
}

puts “---------------------------”
fo.show

puts “---------------------------”
fo.color(“blue”)
puts fo.color

puts “---------------------------”
fo.show


#2

cibercitizen1:

I tried to

class Foo
attr_accessor :bar1, :bar2

def initialize( &bloc )
instance_eval( &bloc )
end
end

and then

f = Foo.new {
bar1 = 12345
bar2 = 44444
}

but this doesn’t work
unless you write @bar1=12345 in the block, as
Ruby does not consider bar1= a method call but an assignment.

Right, unless you precede it with self:

f = Foo.new {
self.bar1 = 12345
self.bar2 = 44444
}

– Shot


#3

On Mon, Nov 24, 2008 at 11:17 PM, Shot (Piotr S.) removed_email_address@domain.invalid
wrote:

end

and then

f = Foo.new {
bar1 = 12345
bar2 = 44444
}

but this doesn’t work

Right, unless you precede it with self:

f = Foo.new {
self.bar1 = 12345
self.bar2 = 44444
}

Another idiom is to yield self to the block like so:

irb(main):001:0> class Foo
irb(main):002:1> attr_accessor :bar1, :bar2
irb(main):003:1> def initialize
irb(main):004:2> yield self
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> f = Foo.new {|foo| foo.bar1 = “test”; foo.bar2 =
“test2”}
=> #<Foo:0xb7b72dcc @bar2=“test2”, @bar1=“test”>

Jesus.


#4

My solution above for having

fo = Foo.new() {
color “red”
height 50
}

by defining

class Foo
extend MyAccessor

my_attr(:title, “default title”)
my_attr(:height, 100)
my_attr(:color, ‘black’)
def initialize( &bloc )
instance_eval( &bloc )
end # def
end # class

is buggy because the ’ ’ in
@#{nou} = s || @#{nou} || ‘#{defval}’
ends with variables being always strings.

This one works better

module MyAccessor
def my_attr (nou, defval=nil)
if defval == nil
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou}
end”
elsif defval.class==String
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou} || ‘#{defval}’
end”
else
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou} || #{defval}
end”
end
#puts “class_eval”, code
class_eval code
end # def my_attr
end # module