Forum: Ruby Question on class-declarations

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.
iamkris (Guest)
on 2005-11-29 00:39
(Received via mailing list)
Yet Another Ruby N. (YARN) question.

I see Rails makes extensive use of class-declarations.

For example:

class LineItem < ActiveRecord::Base
  belongs_to :product
......

belongs_to is a class-declaration in the above code. Coming from a C
family of languages I could not grasp this initially. When does this
code get executed - does it happen when the class is loaded for the
first time or every time a new instance of the class is created?

In this case I think the class-declaration code(belongs_to) looks at
the corresponding database table structure and injects attributes and
methods into the LineItem class. Am I right?

I created the following example

class B
 def hello
   print "Hello"
 end
end

class D < B
  hello
 def bye
   print "bye"
 end
end

I tried this in irb and got an error. Why doesn't this work? In Rails I
think mixins are used to provide this kind of functionality.

To me these seem to be idioms of the language. Is there a site where
you could find gems like these?

Thanks.
dblack (Guest)
on 2005-11-29 00:51
(Received via mailing list)
Hi --

On Tue, 29 Nov 2005, Kris wrote:

> Yet Another Ruby N. (YARN) question.

Isn't Ruby N. redundant? :-)  But anyway, welcome.

> I see Rails makes extensive use of class-declarations.
>
> For example:
>
> class LineItem < ActiveRecord::Base
>  belongs_to :product
> ......
>
> belongs_to is a class-declaration in the above code. Coming from a C

It's not a declaration; it's a call to a method, specifically a class
method of ActiveRecord::Base.  (Actually, because of the way the
ActiveRecord code base is engineered, it's sort of a
pseudo-class-method, but I strongly advise you not to worry about
that :-)  For all practical purposes it's a class method.)

A class method is a method defined directly on a class object.  Here's
a simple example:

   class C
     def C.hello
       puts "hi"
     end
   end

   C.hello    # hi

Note that the class method C.hello is completely unrelated to C's
instance methods.  In fact, you could have an instance method with the
same name, with no conflict:

   class C
     def hello
       puts "hi from instance!"
     end
   end

   C.hello      # hi
   C.new.hello  # hi from instance!

> family of languages I could not grasp this initially. When does this
> code get executed - does it happen when the class is loaded for the
> first time or every time a new instance of the class is created?

It happens when the class definition itself is executed -- which will
be when the file is loaded.

> In this case I think the class-declaration code(belongs_to) looks at
> the corresponding database table structure and injects attributes and
> methods into the LineItem class. Am I right?

Yes.  The route to this is somewhat circuitous, but basically an
association method will trigger the matching up of table names,
thing_id fields, etc., and dynamically create the methods that allow
the object access to the associated class.

> def bye
>   print "bye"
> end
> end
>
> I tried this in irb and got an error. Why doesn't this work? In Rails I
> think mixins are used to provide this kind of functionality.

It doesn't work because hello and bye are both instance methods -- but
by calling hello in the definition scope of D, you're treating it like
a class method.  You're basically saying: send the message "hello" to
the class object D, which doesn't do anything because D doesn't
respond to that message.

> To me these seem to be idioms of the language. Is there a site where
> you could find gems like these?

I'm not quite sure what you mean... but I hope the above is helpful
:-)


David
leavengood (Guest)
on 2005-11-29 00:55
(Received via mailing list)
On 11/28/05, Kris <removed_email_address@domain.invalid> wrote:
> belongs_to is a class-declaration in the above code. Coming from a C
> family of languages I could not grasp this initially. When does this
> code get executed - does it happen when the class is loaded for the
> first time or every time a new instance of the class is created?

It will help if you think about class definitions as being as much
executable code as the rest of your script. Then think about in what
context code within a class definition is executed. For example:

irb(main):001:0> class C
irb(main):002:1>   p self
irb(main):003:1>   p self.class.name
irb(main):004:1>   def foo
irb(main):005:2>     p self
irb(main):006:2>     p self.class.name
irb(main):007:2>   end
irb(main):008:1> end
C
"Class"
=> nil
irb(main):009:0> C.new.foo
#<C:0x2b5ab80>
"C"
=> nil

As you can see the code that prints out self and self.class.name
within the class is executed when the class is created, and the
context of the code is the class itself. Then when you run the
instance method the context is an instance of the class.

So given this, where do you think the method belongs_to is defined?
When it is called, self is the class itself, which is an instance of
Class, so the methods much be instance methods of Class:

irb(main):010:0> class Class
irb(main):011:1>   def print_this(symbol)
irb(main):012:2>     p symbol
irb(main):013:2>   end
irb(main):014:1> end
=> nil
irb(main):015:0> class C
irb(main):016:1>   print_this :sym
irb(main):017:1> end
:sym
=> nil

> In this case I think the class-declaration code(belongs_to) looks at
> the corresponding database table structure and injects attributes and
> methods into the LineItem class. Am I right?

Yes you've got the idea here.

>  def bye
>    print "bye"
>  end
> end

The problem is you need to define an instance method of the class
Class, not of a super class.

> I tried this in irb and got an error. Why doesn't this work? In Rails I
> think mixins are used to provide this kind of functionality.
>
> To me these seem to be idioms of the language. Is there a site where
> you could find gems like these?

Check this out: http://www.rubygarden.org/ruby?RubyIdioms

Ryan
Daniel S. (Guest)
on 2005-11-29 02:36
(Received via mailing list)
class A
     # A class method
     # could also be named `A.hello'
     def self.hello
       puts "Hello from A.hello"
     end

     # An instance method
     def hello
       puts "Hello from A#hello"
     end
   end

   class B < A
     hello  # -> Hello from A.hello

     # This method will be called each
     # time the class is instantiated
     def initialize
       hello  # -> Hello from A#hello
     end
   end

Class methods are usually referred to as ClassName.method_name, and
instance methods as ClassName#method_name


Cheers,
Daniel
This topic is locked and can not be replied to.