Forum: Ruby statement outside of any method in a class

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.
D4c3a5723bce09a1ca0c352240607f3c?d=identicon&s=25 Paul Smith (psmith)
on 2007-01-11 05:01
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.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-11 05:22
(Received via mailing list)
Hi --

On Thu, 11 Jan 2007, Paul Smith 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
87e41d0d468ad56a3b07d9a6482fd6d5?d=identicon&s=25 Hemant Kumar (gnufied)
on 2007-01-11 05:31
(Received via mailing list)
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.
D4c3a5723bce09a1ca0c352240607f3c?d=identicon&s=25 Paul Smith (psmith)
on 2007-01-11 05:36
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
D4c3a5723bce09a1ca0c352240607f3c?d=identicon&s=25 Paul Smith (psmith)
on 2007-01-11 05:42
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.
87e41d0d468ad56a3b07d9a6482fd6d5?d=identicon&s=25 Hemant Kumar (gnufied)
on 2007-01-11 06:35
(Received via mailing list)
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.

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.
852a62a28f1de229dc861ce903b07a60?d=identicon&s=25 Gavin Kistner (phrogz)
on 2007-01-11 07:15
(Received via mailing list)
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)"
807270f56f26ad90755eef71f2c228fe?d=identicon&s=25 Alex Gutteridge (Guest)
on 2007-01-11 07:17
(Received via mailing list)
On 11 Jan 2007, at 13:36, Paul Smith 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 Gutteridge

Bioinformatics Center
Kyoto University
852a62a28f1de229dc861ce903b07a60?d=identicon&s=25 Gavin Kistner (phrogz)
on 2007-01-11 07:20
(Received via mailing list)
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
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-01-11 10:35
(Received via mailing list)
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 :)  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
This topic is locked and can not be replied to.