Forum: Ruby on Rails Realising a kind of virtual methods

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
ms (Guest)
on 2009-02-19 14:08
(Received via mailing list)
Hey,

I want to realise some kind of virtual methods. I'll explain this with
an example:

Let's assume I've got a class called "Animal". Every "Animal" instance
can have various attributes, which are not fix, they depend on the
annotations associated within the "animal" database table. So I could
create a method called "getAttribute()":

animal = Animal.new()
animal.getAttribute("WEIGHT")

If there's an annotation called "WEIGHT", the weight is returned,
otherwise "nil". The thing is: I don't want to write "getAttribute
(XYZ)" each time to get the data. I want to write:

animal.weight

But there is no predefined accessor method called "weight". Some how,
I must catch this. I've got two ideas, of which I'm not sure whether
they make sense and can be implemented:

1. The accessor methods are created dynamically at runtime, so that
they internally access the annotation data and return what they've
found or "nil".

2. A kind of "catch-all"-method which takes the name of the methode,
which we try to call, as a parameter. Some pseudo-code:

catchAll(nameOfDesiredMethod)
  FindAnnotation(nameOfDesiredMethod) // returning attribute value or
nil
end

I don't know, if there's a known technique for this kind of problem.
But I know, that there's something similar, if you look at the
ActiveRecord find() method. There you can say find_by_attribute, for
example.

It's hard to explain, I did my best.

Thank you for your suggestions!

Best wishes,
ms
Frederick C. (Guest)
on 2009-02-19 14:17
(Received via mailing list)
> 2. A kind of "catch-all"-method which takes the name of the methode,
> example.
ActiveRecord does exactly this for database attributes you might find
nosing around in there is useful. The magic method you are looking for
is method_missing.

Fred
Matt J. (Guest)
on 2009-02-20 04:48
(Received via mailing list)
On Feb 19, 7:07 am, ms <removed_email_address@domain.invalid> wrote:
> animal = Animal.new()
> they make sense and can be implemented:
>

As Fred pointed out, method_missing is what you're thinking of; it's
what
AR uses to handle dynamic finders (find_by_x).

That being said, however, if you're referring to the fields in Ruby
code and
doing so often enough that a shorthand is good - you should really
just have
a DB field for it and be done.

Otherwise, you end up with a table like in this article:
http://thedailywtf.com/Articles/tblStaffDirectory.aspx

...which isn't so good.

Finally, if you're really just interested in attaching a few
"annotation"-style fields
to a model, take a look at serialized columns. Big warning: you gain
flexibility, but
at the cost of losing the ability to query values in SQL. I've used
serialized columns,
for example, to hold some fields that were imported by users from CSV
files and
then exported with the regular data fields to other CSV files. In that
case, my code
didn't care *what* the fields were, it just needed to store them.

--Matt J.
This topic is locked and can not be replied to.