[lnkForumImage]
TotalShareware - Download Free Software

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


 

Luke Renn

3/29/2005 5:58:00 PM

What is the proper term for things like attr :<id> and belongs_to
:<model>, etc. How do you code them? I tried googling around, but
since I don't know what to call it, its a little tough. I looked at
the ActiveRecord code for a few minutes and it looks like they're just
class methods, but I don't understand how ruby interprets it i guess.

Thanks.

--
Luke | PGP: 0xFBE7D8AF
goseigen@comcast.net | 2A44 9EB2 F541 C1F2 D969 56E3 8617 5B7F FBE7 D8AF


17 Answers

Glenn Smith

3/29/2005 6:09:00 PM

0

A similar thing has just been discussed on the RubyOnRails list, and
James Britt gave a good example which I'll paste here. It's
implemented (in this case at least) using "meta programming" which is
something I'm just reading up on at the moment, because it foxed me
to!!

Here is James' example:

A simple example

# Meta-programming
# Add a public array property to an object instance

class Meta
def self.has_many( sym )
attr_tmp = "def #{sym.to_s} \n"
attr_tmp << " @#{sym.to_s} = [] unless @#{sym.to_s}\n"
attr_tmp << " @#{sym.to_s}; end"
eval ( attr_tmp )
end
end

class Foo < Meta
has_many :foo
has_many :baz
end

f = Foo.new

# See what methds the new object has ...
puts (f.methods - Object.methods ).inspect # ["foo", "baz"]

f.foo.push "X"
f.baz << "hello"

p f.foo.first # "X"
p f.baz # ["hello"]


James Britt




On Wed, 30 Mar 2005 02:57:58 +0900, Luke Renn <goseigen@comcast.net> wrote:
> What is the proper term for things like attr :<id> and belongs_to
> :<model>, etc. How do you code them? I tried googling around, but
> since I don't know what to call it, its a little tough. I looked at
> the ActiveRecord code for a few minutes and it looks like they're just
> class methods, but I don't understand how ruby interprets it i guess.
>
> Thanks.
>
> --
> Luke | PGP: 0xFBE7D8AF
> goseigen@comcast.net | 2A44 9EB2 F541 C1F2 D969 56E3 8617 5B7F FBE7 D8AF
>
>


--

All the best
Glenn
Aylesbury, UK


Glenn Smith

3/29/2005 6:09:00 PM

0

A similar thing has just been discussed on the RubyOnRails list, and
James Britt gave a good example which I'll paste here. It's
implemented (in this case at least) using "meta programming" which is
something I'm just reading up on at the moment, because it foxed me
to!!

Here is James' example:

A simple example

# Meta-programming
# Add a public array property to an object instance

class Meta
def self.has_many( sym )
attr_tmp = "def #{sym.to_s} \n"
attr_tmp << " @#{sym.to_s} = [] unless @#{sym.to_s}\n"
attr_tmp << " @#{sym.to_s}; end"
eval ( attr_tmp )
end
end

class Foo < Meta
has_many :foo
has_many :baz
end

f = Foo.new

# See what methds the new object has ...
puts (f.methods - Object.methods ).inspect # ["foo", "baz"]

f.foo.push "X"
f.baz << "hello"

p f.foo.first # "X"
p f.baz # ["hello"]


James Britt




On Wed, 30 Mar 2005 02:57:58 +0900, Luke Renn <goseigen@comcast.net> wrote:
> What is the proper term for things like attr :<id> and belongs_to
> :<model>, etc. How do you code them? I tried googling around, but
> since I don't know what to call it, its a little tough. I looked at
> the ActiveRecord code for a few minutes and it looks like they're just
> class methods, but I don't understand how ruby interprets it i guess.
>
> Thanks.
>
> --
> Luke | PGP: 0xFBE7D8AF
> goseigen@comcast.net | 2A44 9EB2 F541 C1F2 D969 56E3 8617 5B7F FBE7 D8AF
>
>


--

All the best
Glenn
Aylesbury, UK


John Wilger

3/29/2005 6:10:00 PM

0

On Wed, 30 Mar 2005 02:57:58 +0900, Luke Renn <goseigen@comcast.net> wrote:
> the ActiveRecord code for a few minutes and it looks like they're just
> class methods, but I don't understand how ruby interprets it i guess.

You're absolutely correct that they're just class methods. In Ruby
(unlike many other languages) the code that defines a class is much
more than just a "definition". The code between "class Foo ... end" is
executed just like any other part of your program. Perhaps this simple
example using a global variable will help clear it up:

irb(main):001:0> $foo = 'bar'
=> "bar"
irb(main):002:0> $foo
=> "bar"
irb(main):003:0> class FooChanger
irb(main):004:1> $foo = 'baz'
irb(main):005:1> end
=> "baz"
irb(main):006:0> $foo
=> "baz"

--
Regards,
John Wilger

-----------
Alice came to a fork in the road. "Which road do I take?" she asked.
"Where do you want to go?" responded the Cheshire cat.
"I don't know," Alice answered.
"Then," said the cat, "it doesn't matter."
- Lewis Carrol, Alice in Wonderland


Luke Renn

3/29/2005 6:17:00 PM

0

* John Wilger <johnwilger@gmail.com> [2005-03-30 03:09:57 +0900]:

> more than just a "definition". The code between "class Foo ... end" is
> executed just like any other part of your program. Perhaps this simple

That's what i was thinking. So anything in between class Foo ... end
is like a static { } block in a java class. Thanks to both of you for
clearing that up.

--
Luke | PGP: 0xFBE7D8AF
goseigen@comcast.net | 2A44 9EB2 F541 C1F2 D969 56E3 8617 5B7F FBE7 D8AF


Patrick Hurley

3/29/2005 6:18:00 PM

0

On Wed, 30 Mar 2005 02:57:58 +0900, Luke Renn <goseigen@comcast.net> wrote:
> What is the proper term for things like attr :<id> and belongs_to
> :<model>, etc. How do you code them? I tried googling around, but
> since I don't know what to call it, its a little tough. I looked at
> the ActiveRecord code for a few minutes and it looks like they're just
> class methods, but I don't understand how ruby interprets it i guess.
>
> Thanks.

I am not a Ruby expert (yet :-), but the first thing to realize is
that attr, etc are just normal methods. And remembering I am far from
a Ruby expert, I wrote the following code for personal exploration on
the same topic. It adds attr_class_(reader|writer|accessor) methods to
Module so that any other class or module can then provide easy access
to class data variables. Note all it does use class eval to "write"
the access methods -- I do not know if this is what module does or if
there is a substantially better technique. I would prefer to have used
a closure over class_eval, but could not figure out how (if it is
possible).

Patrick

class Module
def attr_class_reader(sym)
self.class_eval <<ATTR
def self.#{sym}
@@#{sym}
end
ATTR
end

def attr_class_writer(sym)
self.class_eval <<ATTR
def self.#{sym}=(new_value)
@@#{sym} = new_value
end
ATTR
end

def attr_class_accessor(sym)
attr_class_reader(sym)
attr_class_writer(sym)
end
end


Florian Gross

3/29/2005 7:56:00 PM

0

Glenn Smith wrote:

> Here is James' example:
>
> A simple example
>
> # Meta-programming
> # Add a public array property to an object instance
>
> class Meta
> def self.has_many( sym )
> attr_tmp = "def #{sym.to_s} \n"
> attr_tmp << " @#{sym.to_s} = [] unless @#{sym.to_s}\n"
> attr_tmp << " @#{sym.to_s}; end"
> eval ( attr_tmp )
> end
> end

And here it is without an eval:

class Meta
def self.has_many(sym)
ivar = :"@#{sym}"
define_method(sym.to_sym) do
new_value = instance_variable_get(ivar) || []
instance_variable_set(ivar, new_value)
new_value
end
end
end

B. K. Oxley (binkley)

3/29/2005 8:04:00 PM

0

Florian Gross wrote:
> Glenn Smith wrote:
>> class Meta
>> def self.has_many( sym )
>> attr_tmp = "def #{sym.to_s} \n"
>> attr_tmp << " @#{sym.to_s} = [] unless @#{sym.to_s}\n"
>> attr_tmp << " @#{sym.to_s}; end"
>> eval ( attr_tmp )
>> end
>> end
>
> class Meta
> def self.has_many(sym)
> ivar = :"@#{sym}"
> define_method(sym.to_sym) do
> new_value = instance_variable_get(ivar) || []
> instance_variable_set(ivar, new_value)
> new_value
> end
> end
> end

What is the difference between these two approaches?

* Is one more 'culturally correct'?
* Does one perform better?
* Is one more future-proof?


Thanks,
--binkley


Austin Ziegler

3/29/2005 8:30:00 PM

0

On Wed, 30 Mar 2005 05:03:48 +0900, B. K. Oxley (binkley)
<binkley@alumni.rice.edu> wrote:
> Florian Gross wrote:
> > class Meta
> > def self.has_many(sym)
> > ivar = :"@#{sym}"
> > define_method(sym.to_sym) do
> > new_value = instance_variable_get(ivar) || []
> > instance_variable_set(ivar, new_value)
> > new_value
> > end
> > end
> > end
> What is the difference between these two approaches?

Florian's will only work on Ruby 1.8 or later and avoids some of the
concerns that people have around "eval".

-austin
--
Austin Ziegler * halostatue@gmail.com
* Alternate: austin@halostatue.ca


B. K. Oxley (binkley)

3/29/2005 8:33:00 PM

0

Austin Ziegler wrote:
> Florian's will only work on Ruby 1.8 or later and avoids some of the
> concerns that people have around "eval".

Being new to Ruby, what sorts of concerns?

Thanks,
--binkley


ptkwt

3/29/2005 8:33:00 PM

0

In article <4249B4AA.2090602@alumni.rice.edu>,
B. K. Oxley (binkley) <binkley@alumni.rice.edu> wrote:
>Florian Gross wrote:
>> Glenn Smith wrote:
>>> class Meta
>>> def self.has_many( sym )
>>> attr_tmp = "def #{sym.to_s} \n"
>>> attr_tmp << " @#{sym.to_s} = [] unless @#{sym.to_s}\n"
>>> attr_tmp << " @#{sym.to_s}; end"
>>> eval ( attr_tmp )
>>> end
>>> end
>>
>> class Meta
>> def self.has_many(sym)
>> ivar = :"@#{sym}"
>> define_method(sym.to_sym) do
>> new_value = instance_variable_get(ivar) || []
>> instance_variable_set(ivar, new_value)
>> new_value
>> end
>> end
>> end
>
>What is the difference between these two approaches?
>
>* Is one more 'culturally correct'?
>* Does one perform better?
>* Is one more future-proof?

The second approach would generally be considered 'better'. eval must be
used with care (security issues, debugging is harder, etc.). The second
approach doesn't use eval so that's why it would generally be preferred.
Performance differences between the two are probably negligable. I
suspect that either approach would work in the future.

Sometimes you need to use eval (or it's cousins instance_eval and
class_eval - the latter should probably be preferred where possible) and
it's great to have it's power available so I'm not saying you should
_never_ use eval.

Phil