# My attr\_accessor

**URL:** <https://www.ruby-forum.com/t/my-attr-accessor/154053>\
**Category:** Ruby\
**Created:** [November 24, 2008, 10:45pm UTC](https://www.ruby-forum.com/t/my-attr-accessor/154053 "2008-11-24T22:45:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cibercitizen1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4da419/32.png) [@cibercitizen1](https://www.ruby-forum.com/u/cibercitizen1)\
**Post date:** [November 24, 2008, 10:45pm UTC](https://www.ruby-forum.com/t/my-attr-accessor/154053/1 "2008-11-24T22:45:41Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![cibercitizen1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4da419/32.png) [@cibercitizen1](https://www.ruby-forum.com/u/cibercitizen1)\
**Post date:** [November 24, 2008, 11:22pm UTC](https://www.ruby-forum.com/t/my-attr-accessor/154053/2 "2008-11-24T23:22:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![cibercitizen1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4da419/32.png) [@cibercitizen1](https://www.ruby-forum.com/u/cibercitizen1)\
**Post date:** [November 25, 2008, 9:06am UTC](https://www.ruby-forum.com/t/my-attr-accessor/154053/3 "2008-11-25T09:06:36Z")

</div>

On Mon, Nov 24, 2008 at 11:17 PM, Shot (Piotr S.) [removed\_email\_address@domain.invalid](mailto: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.

---

<div class="post-metadata">

**Author:** ![cibercitizen1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4da419/32.png) [@cibercitizen1](https://www.ruby-forum.com/u/cibercitizen1)\
**Post date:** [November 25, 2008, 11:05pm UTC](https://www.ruby-forum.com/t/my-attr-accessor/154053/4 "2008-11-25T23:05:40Z")

</div>

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
