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?
···
--
Posted via http://www.ruby-forum.com/.
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
···
--
Posted via http://www.ruby-forum.com/\.
P.S. If you want to defer loading of classes until when they are used,
have a look at Kernel#autoload
···
--
Posted via http://www.ruby-forum.com/.
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?
···
--
Posted via http://www.ruby-forum.com/\.
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:
--
Posted via http://www.ruby-forum.com/\.
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
···
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?
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/