Statement outside of any method in a class

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.

···

--
Posted via http://www.ruby-forum.com/.

Hi --

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?)

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

···

On Thu, 11 Jan 2007, Paul Smith wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

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.

···

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

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.

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

--
Posted via http://www.ruby-forum.com/\.

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 Kumar wrote:

···

On Thu, 2007-01-11 at 13:01 +0900, Paul Smith 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.

--
Posted via http://www.ruby-forum.com/\.

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.

···

On Thu, 2007-01-11 at 13:42 +0900, Paul Smith 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.

Paul Smith 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)"

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 Gutteridge

Bioinformatics Center
Kyoto University

···

On 11 Jan 2007, at 13:36, Paul Smith 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?

   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.

On Behalf Of Paul Smith:
# 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

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