attr / attr_accessor

M

Markus Werner

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
 
H

Henrik Ronellenfitsch

Markus said:
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
 
G

gabriele renzi

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/CapturingMethods.html

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
 
M

Markus Werner

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

Hi,

Henrik Ronellenfitsch ha scritto:

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
 
M

Mark Hubbart

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
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top