Statement outside of any method in a class


#1

Newbie question:

In the following code:

class Person < ActiveRecord::Base
validates_presence_of :first_name
end

validates_presence_of is a method call that is
specified outside of any method in class Person.

Could someone explain what the invocation model is
for that statement that is not bound to any method
within a class (i.e. when is that statement executed?)

Thanks.


#2

Hi –

On Thu, 11 Jan 2007, Paul S. wrote:

Could someone explain what the invocation model is
for that statement that is not bound to any method
within a class (i.e. when is that statement executed?)

It’s the same, in the abstract, as the invocation model generally: a
“bareword”-style method is automatically invoked on the current
default object, self. At the outer level of a class definition, self
is the class object itself. So what you’re seeing is a call to a
class method.

Here’s a little X-ray of what’s going on:

class SomeClass
def self.do_something
puts “Hi!”
end
end

class C < SomeClass
puts “self right now is #{self}.” # self right now is C.
do_something # Hi!
end

There are more nuances but that’s the basic scenario.

David


#3

On Thu, 2007-01-11 at 13:01 +0900, Paul S. wrote:

Hmm validates_presence_of method is not “outside any method” in class
Person actually. Most probably (i.e taking into account rails meta
magic), validates_presence_of is a class method, which is defined in
class ActiveRecord::Base.

So, when Person class inherits ActiveRecord::Base class it also inherits
method validates_presence_of and above mentioned line invokes the method
with argument :first_name.

class Foobar
def self.sayfoo arg
puts “You said #{arg}”
end
end

class Baz < Foobar
sayfoo :rubyrocks
end

Output #=> “You said rubyrocks”

Unlike C++, where you can have class or instance methods of a class(i.e
static or normal methods of class) defined outside class definition, in
Ruby its always inside class.


#4

Thanks Hemant. However, as I mentioned in my last reply, it is not clear
to me what triggers the execution of a statement such as “sayfoo
:rubyrocks” in your example. When the class is loaded, when an instance
is created, ???

Thanks.

P.

Hemant K. wrote:

On Thu, 2007-01-11 at 13:01 +0900, Paul S. wrote:

Hmm validates_presence_of method is not “outside any method” in class
Person actually. Most probably (i.e taking into account rails meta
magic), validates_presence_of is a class method, which is defined in
class ActiveRecord::Base.

So, when Person class inherits ActiveRecord::Base class it also inherits
method validates_presence_of and above mentioned line invokes the method
with argument :first_name.

class Foobar
def self.sayfoo arg
puts “You said #{arg}”
end
end

class Baz < Foobar
sayfoo :rubyrocks
end

Output #=> “You said rubyrocks”

Unlike C++, where you can have class or instance methods of a class(i.e
static or normal methods of class) defined outside class definition, in
Ruby its always inside class.


#5

Thanks for the explanation David.

However, it is still not clear to me when these statements are invoked.

In your example, what triggers the execution of the 2 statements?

class C < SomeClass
puts “self right now is #{self}.” # self right now is C.
do_something # Hi!
end

When the class is loaded, when an instance of that class is created?
Is this similar to a static initialization block in Java?

P.

Could someone explain what the invocation model is
for that statement that is not bound to any method
within a class (i.e. when is that statement executed?)

It’s the same, in the abstract, as the invocation model generally: a
“bareword”-style method is automatically invoked on the current
default object, self. At the outer level of a class definition, self
is the class object itself. So what you’re seeing is a call to a
class method.

Here’s a little X-ray of what’s going on:

class SomeClass
def self.do_something
puts “Hi!”
end
end

class C < SomeClass
puts “self right now is #{self}.” # self right now is C.
do_something # Hi!
end

There are more nuances but that’s the basic scenario.

David


#6

On Thu, 2007-01-11 at 13:42 +0900, Paul S. wrote:

Thanks Hemant. However, as I mentioned in my last reply, it is not clear
to me what triggers the execution of a statement such as “sayfoo
:rubyrocks” in your example. When the class is loaded, when an instance
is created, ???

Thanks.

On a broader perspective, we can say when the class is loaded, when you
define a class like this in your code:

class Baz < Foobar
sayfoo :rubyrocks
end

An object called Baz starts to exist in current Runtime, which is an
instance of class Class.

So, when method sayfoo gets invoked when object Baz is created or in
other words, we can say when class is loaded.


#7

On 11 Jan 2007, at 13:36, Paul S. wrote:

end

When the class is loaded, when an instance of that class is created?
Is this similar to a static initialization block in Java?

P.

Hemant may have already answered your question, but as an aside the
easiest way to check these things in Ruby is to use irb to test:

irb(main):001:0> class A
irb(main):002:1> def self.doit
irb(main):003:2> puts “hi”
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class B < A
irb(main):007:1> puts “self: #{self}”
irb(main):008:1> doit
irb(main):009:1> end
self: B
hi
=> nil
irb(main):010:0> A.new
=> #<A:0x340fe4>
irb(main):011:0> B.new
=> #<B:0x33aab8>

Does that make it clearer? doit only gets run when the B class is
defined, not when an instance is created.

Alex G.

Bioinformatics Center
Kyoto University


#8

Phrogz wrote:

class Foo
puts “Inside Foo on line 4”
def bar
puts “Running #bar method (line 6)”
end
puts “All done with #{self} (line 8)”
end

Even more enlightening, add two lines:

class Foo
puts “Inside Foo on line 4”
p self.instance_methods(false)
def bar
puts “Running #bar method (line 7)”
end
p self.instance_methods(false)
puts “All done with #{self} (line 10)”
end


#9

Paul S. wrote:

Thanks for the explanation David.

However, it is still not clear to me when these statements are invoked.

In your example, what triggers the execution of the 2 statements?
[snip]
When the class is loaded, when an instance of that class is created?
Is this similar to a static initialization block in Java?

Instead of asking and waiting for an answer, perhaps just try running
the following code:

puts “Line 1”

class Foo
puts “Inside Foo on line 4”
def bar
puts “Running #bar method (line 6)”
end
puts “All done with #{self} (line 8)”
end

puts “Line 11”

f = Foo.new
f.bar

puts “Last line (16)”


#10

On Behalf Of Paul S.:

is not clear

to me what triggers the execution of a statement such as "sayfoo

:rubyrocks" in your example.

When the class is loaded, when

yes, when class is first loaded or redefined.

an instance is created, ???

no, otherwise it gets executed many times per instance (assumming of
course you just want it to run once :slight_smile: You can use initialize() if you
want something invoked per instance-iation.

btw, you can monitor behavior using irb and debug. but in case you doubt
if they do some magic, you can also do tracing. try putting the ff code
at the beginning of the program you want to observe,

#----
set_trace_func proc do |event, file, line, id, binding, classname|
printf “%8s %s:%2d%10s %8s\n”, event, file, line, id, classname
end
#----

ruby is really very open. have fun.

kind regards -botp