Forum: Ruby Ruby Execution

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.
D1309ef77561e3cdf0ddcab60b244e52?d=identicon&s=25 Mike Stephens (aspirer)
on 2009-06-04 10:48
If you have a script with a lot of classes, does the interpreter read
through and 'execute' each class even though they haven't yet been
called? Similarly, if you 'require' other libraries, does the
interpreter insert the code and execute it all, rather than if and when
each class is first referenced?
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-06-04 12:27
Mike Stephens wrote:
> If you have a script with a lot of classes, does the interpreter read
> through and 'execute' each class even though they haven't yet been
> called?

Yes. Everything is done at runtime.

* require 'foo' just loads and executes the code in foo.rb.

* Code of the form "class X; def m; ..." has the runtime effect of
defining methods in classes.

* It's quite common to have code which sets up variables and/or
constants too. For example:

class X
  @count = 0

  def self.create(*args)
    @count += 1
    new(*args)
  end

  def self.count
    @count
  end
end

a = X.create
b = X.create
puts X.count
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-06-04 12:28
P.S. If you want to defer loading of classes until when they are used,
have a look at Kernel#autoload
D1309ef77561e3cdf0ddcab60b244e52?d=identicon&s=25 Mike Stephens (aspirer)
on 2009-06-04 13:40
Brian Candler wrote:
> P.S. If you want to defer loading of classes until when they are used,
> have a look at Kernel#autoload

Is this the norm? I would have thought it would be a real problem
parsing big frameworks with myriads of classes everytime you want to
make a simple call. Is there a way of keeping a parsed script cached eg
for a web site that is handling hundreds of users doing the same sorts
of things eg browsing product lists?
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-06-04 16:06
Mike Stephens wrote:
> Brian Candler wrote:
>> P.S. If you want to defer loading of classes until when they are used,
>> have a look at Kernel#autoload
>
> Is this the norm? I would have thought it would be a real problem
> parsing big frameworks with myriads of classes everytime you want to
> make a simple call.

Once a library has been require'd once, then the fact that this has been
done is recorded (in variable $LOADED_FEATURES), and so it won't be
loaded again. If you want to check this out: require returns 'true' if
it had to load something, and 'false' if it didn't.

Autoload goes one stage further: it won't load the file unless the
constant doesn't exist.

-------------------------------------------------------- Kernel#autoload
     autoload(module, filename)   => nil
------------------------------------------------------------------------
     Registers _filename_ to be loaded (using +Kernel::require+) the
     first time that _module_ (which may be a +String+ or a symbol) is
     accessed.

        autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")

That is: the first time you try to do MyModule.foo, the file is
required, which (presumably) defines MyModule. Since it now exists, the
next call to MyModule.bar won't touch any source files.

> Is there a way of keeping a parsed script cached eg
> for a web site that is handling hundreds of users doing the same sorts
> of things eg browsing product lists?

As I say, once the file has been loaded, it's loaded.

The only problem comes if you quit the process and restart it, as then
it obviously has to load everything again from scratch. I wrote
something which can help with that:
http://github.com/candlerb/snailgun
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-06-04 22:45
(Received via mailing list)
On 04.06.2009 13:40, Mike Stephens wrote:
> Brian Candler wrote:
>> P.S. If you want to defer loading of classes until when they are used,
>> have a look at Kernel#autoload
>
> Is this the norm? I would have thought it would be a real problem
> parsing big frameworks with myriads of classes everytime you want to
> make a simple call. Is there a way of keeping a parsed script cached eg
> for a web site that is handling hundreds of users doing the same sorts
> of things eg browsing product lists?

Maybe this additional bit of information helps.  When you run a Ruby
script the first thing that happens is that it is parsed and translated
into an internal binary representation (which one depends on the version
and platform used, e.g. ruby 1.9 is differently than 1.8 than JRuby).
Only then it is executed, which basically means that the internal
representation is interpreted in some way.  This is typically pretty
efficient compared to the bourne shell approach of doing the parsing
line based.

I have no insights into JRuby but knowing the JVM it would even be
possible that eventually your Ruby code has become machine code when the
hot spot engine decides it should compile it.

To sum it up: you shouldn't be too concerned about the efficiency of
that approach.  The issue you are bringing up is rather valid in
situations where a largish application (i.e. multiple files) is needed
to execute only small interactions (for example when doing classic CGI
where a new process is started for each request).

Kind regards

  robert
This topic is locked and can not be replied to.