Question on class-declarations


#1

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.


#2

Hi –

On Tue, 29 Nov 2005, Kris wrote:

Yet Another Ruby N. (YARN) question.

Isn’t Ruby N. redundant? :slight_smile: 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 :slight_smile: 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
:slight_smile:

David


#3

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


#4

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