[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

attr / attr_accessor

Markus Werner

12/30/2004 1:35:00 PM

Hi Ruby Folk,


I'm quite a newbie in programming. Last year I came to perl and now I'm
testing ruby.

I like the methods attr, attr_*. But there is one drawback. You can't tell the
methode that there should be a standard code that will be executed on every
access. IMHO The best would be a pre and a posthook.

I use the module Class::Methodmaker in perl, were this is possible. Surely I
can write (If I would know how) a own Class to handle this needs. But since
attr_ is so a nice standandard feature I'm the opionion that the feature I
ask for, would be a good enhancement.

Happy New Year

Markus



5 Answers

Henrik Ronellenfitsch

12/30/2004 1:58:00 PM

0

Markus Werner wrote:
> access. IMHO The best would be a pre and a posthook.

You can already have that kind of thing.
attr_ are actually simply another way to write the following methods:

def variable
@variable
end

def variable=(value)
@variable=value
end

If you write these methods yourself instead of using the
attr_-construct, you can do whatever you want in the methods and it
still looks the same to everyone who uses your class.

Greetings,
Henrik

gabriele renzi

12/30/2004 2:40:00 PM

0

Henrik Ronellenfitsch ha scritto:

>
> If you write these methods yourself instead of using the
> attr_-construct, you can do whatever you want in the methods and it
> still looks the same to everyone who uses your class.
>

I /think/ he knew this and was looking for a way to define a bunch of
attributes with a common behaviour, say,

class Foo
attr_with_logging :foo
end
Foo.new.foo=10 #Foo::Logger.log "changed foo in instance 123456"

This is not hard to do, and has imvho, little usage so I don't think it
would be needed in core ruby. But this may be an example of "I Don't
Have It So I Don't Need It".

Anyway, you could take a look at how mauricio fernandez implemented
simple AOP in ~20 lines of ruby here:
http://www.thekode.net/ruby/techniques/CapturingMe...

or just use something like:

##warning dumb implementation ahead


class Module
def attr_with_pre_hook(sym,&blk) #just handles accessors
define_method(sym) do
tmp=instance_variable_get "@"+sym.to_s
blk.call(tmp)
tmp
end
end
end

class Foo
attr_writer :bar
attr_with_pre_hook(:bar) {|b| puts b }
end

f=Foo.new
f.bar=20
p f.bar

Markus Werner

12/30/2004 3:13:00 PM

0

On Thursday 30 December 2004 15:41, gabriele renzi wrote:

Hi,


> Henrik Ronellenfitsch ha scritto:
> > If you write these methods yourself instead of using the
> > attr_-construct, you can do whatever you want in the methods and it
> > still looks the same to everyone who uses your class.

Hmmm...

don't got your mail yet.


>
> I /think/ he knew this and was looking for a way to define a bunch of
> attributes with a common behaviour, say,

You right.
>
> class Foo
> attr_with_logging :foo
> end
> Foo.new.foo=10 #Foo::Logger.log "changed foo in instance 123456"

For example I playing around with vapor.rubyforge.org and you need to call the
methode object.mark_dirty everytime you write to the attribute.

But I see it's not to hard to implement althoug I'm not able to understand
your code, for now.
But I will...

regards

Markus







Henrik Ronellenfitsch

12/30/2004 3:27:00 PM

0

Markus Werner wrote:
>>I /think/ he knew this and was looking for a way to define a bunch of
>>attributes with a common behaviour, say,
>
> You right.

OK, I misunderstood you :)

Mark Hubbart

12/31/2004 9:43:00 PM

0

On Thu, 30 Dec 2004 22:34:40 +0900, Markus Werner
<markus.werner@wobcom.de> wrote:
> Hi Ruby Folk,
>
> I'm quite a newbie in programming. Last year I came to perl and now I'm
> testing ruby.
>
> I like the methods attr, attr_*. But there is one drawback. You can't tell the
> methode that there should be a standard code that will be executed on every
> access. IMHO The best would be a pre and a posthook.


Perhaps:

class Module
def attr_writer_proc(*args, &block)
names = args.map{|s| s.to_sym}
names.each do |name|
define_method "#{name}=" do |val|
instance_variable_set "@#{name}", block.call(val)
end
end
end
def attr_reader_proc(*args, &block)
names = args.map{|s| s.to_sym}
names.each do |name|
define_method name do
block.call instance_variable_get("@#{name}")
end
end
end
end

This would act as a combo pre-hook and data filter:

class Foo
# make sure the values are strings
attr_writer_proc :foo, :bar do |val|
val.to_str
end

# we only want to store copies the objects passed
attr_writer_proc(:baz){|val| val.dup }

# log changes to quux
attr_writer_proc(:quux){|val| log("setting quux to %p"%[val]); val }
end

this could conceivably be wrapped up into the attr_writer/attr_reader
methods, since they currently don't take blocks... Also, it might be
handy to check the arity of the block and pass the variable name as an
optional second argument.

hth,
Mark