I understand the subtle differences between require, load and autoload in Ruby, but my question is, how do you know which one to use?
Other than being able to "wrap" a load in an anonymous module, require seems to be preferred.
But then autoload allows you to lazy load files -- which sounds fantastic but I'm not sure practically what you gain over require
Is one method preferred over the other? Is there a situation where one method stands out?
Generally, you should use require. load will re-load the code every time, so if you do it from several modules, you will be doing a lot of extra work. The lazyness of autoload sounds nice in theory, but many Ruby modules do things like monkey-patching other classes, which means that the behavior of unrelated parts of your program may depend on whether a given class has been used yet or not.
If you want to make your own automatic reloader that loads your code every time it changes or every time someone hits a URL (for development purposes so you don't have to restart your server every time), then using load for that is reasonable.
mylibrary.rb
puts "I was loaded!"
class MyLibrary
end
Try in irb
irb(main):001:0> require 'mylibrary'
I was loaded!
=> true
irb(main):001:0> autoload :MyLibrary, 'mylibrary'
=> nil
irb(main):002:0> MyLibrary.new
I was loaded!
=> #<MyLibrary:0x0b1jef>
See the difference.
here's what you gain with autoload over require:
autoload is primarily for speeding up the initialization phase of your Ruby program or Rails application. By not loading the resources until they are needed, it can speed up things quite a bit.
Another advantage is that you may not need to load some parts of the code, if the user doesn't use certain features -- thereby improving load time and reducing the memory footprint.
Apart from what others have already told you, future of autoload is uncertain. It was scheduled to be deprecated in Ruby 2.0, but the deprecation wasn't made in time for the 2.0 feature freeze. It is now expected that autoload will be deprecated in Ruby 2.1, but that is not even certain anymore.
Here're the use cases for each method.
load to pick up any changes you made to a file while the program is running.
autoload to speed up the initialization of your library by lazily loading the modules.
require when you want to use external gems.
require_relative for local files relative to the current working directory.
Source: Understanding the load, autoload, require, and require_relative methods in Ruby
Related
I'm developing a "Rails-less" Ruby daemon for automation (although in theory it runs within a Rails directory). For general purposes and the principle of the matter, I would like to find the (most) "native"/common way to utilize a Ruby version of .present?/.blank?/.empty?/.nil? to identify if an array or a (hash) value exists and is not empty (i.e., [] or {}).
From what I've read (e.g., Stack Overflow) and tested, all of these functions appear to be Rails-specific methods, part of ActiveSupport(?).
Coming from other web/interpreter languages (PHP, Python, JS, etc.), this is a general logic function most languages (with arrays, which are most) have this functionality built in one way or another (e.g., PHP's isset( ... ) or JavaScript's .length).
I understand there are RegEx workarounds for .blank?, but .present? seems it would require exception handling to identify if it's "present"). I'm having a hard time believing it doesn't exist, but there's little talk about Ruby without Rails' involvement.
Active Support is broken in small pieces so that you can load just what you need. For .blank? and .present? methods it would be enough to require:
require 'active_support/core_ext/object/blank.rb'
As docs say.
Object#nil? , Array#empty? and Hash#empty? already defined so you dont need anything to require to use those.
Make sure active_support gem installed in your system
You can use ActiveSupport without including all rails in your app, that's actually quite common.
nil? and empty? are defined in the standard library.
E.g., String#empty? is simply testing if the length is 0.
To use active support, just install the gem or add it to your gemfile then:
require 'active_support'
The documentation also states you can cherry pick the core extensions you want:
require 'active_support/core_ext/object/blank'
I am confused about the difference between load 'file.rb' and require 'Module'. At Learn Ruby the Hard Way, the example of how to use a module is set up with two files (mystuff.rb and apple.rb):
mystuff.rb
module MyStuff
def MyStuff.apple()
puts "I AM APPLES!"
end
end
apple.rb
require 'mystuff'
MyStuff.apple()
However, when I run apple.rb, either in the Sublime Text console, or with ruby apple.rb, I get a Load Error. I have also tried require 'MyStuff', and require 'mystuff.rb', but I still get the Load Error.
So, I switched the first line of apple.rb to load 'mystuff.rb', which allows it to run. However, if I edit 'mystuff.rb' to be a definition of class MyStuff as opposed to a module MyStuff, there is no difference.
For reference, the Load Error is:
/Users/David/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in require': cannot load such file -- mystuff (LoadError)`
I've peeked into kernel_require.rb and looked at the require definition, but since I'm a Ruby Nuby (indeed, a programming newbie), it was a little overwhelming. Since Learn Ruby the Hard Way hasn't been updated since 2012-10-05, there've probably been some syntax changes for modules. Yes?
require searches a pre-defined list of directories, as discussed in What are the paths that "require" looks up by default?. It's failing because it can't find the mystuff.rb in any of those directories.
load, on the other hand, will look for files in the current directory.
As for:
However, if I edit 'mystuff.rb' to be a definition of class MyStuff as
opposed to a module MyStuff, there is no difference.
I'm not sure I understand what you mean by "no difference". If you mean that the require and load continue to fail and succeed, respectively, that makes sense, as the require failure is independent of the content of the file contents and the code you're testing behaves the same independent of whether Mystuff is a class or a vanilla module.
You can solve this easily by changing
require 'mystuff'
to
require_relative './mystuff'
I am going through the blog Creating mountable Gem:
Its important to note that you should require your dependent gems explicitly in the root file of your gem. Say if your gem is named my_cool_gem, then you should have my_cool_gem.rb created inside lib folder. If your gem is dependent on strong_parameters, then you need to add these lines:
The author did not mention why it is required to have the dependent gems explicitly in the root file. Can some one explain why this needs to be done?
It's just cleaner. What if you had require statements in various files scattered all over your gem? It'd be a mess to easily see all the dependencies.
This statement:
Its important to note that you should require your dependent gems
explicitly in the root file of your gem.
It is not a strict statement that you have to conform to (to be fair to the author, the word is "should", not "must"). Some people prefer to take a different approach, and e.g. require dependencies only in parts of the library that use them.
However, you do need to consider:
Execution order of require statements that define symbols used elsewhere. You cannot call a DSL method that sets up instance methods for you, if the gem that provides the method has not yet been require-d
You should check that you really do require all correct the dependencies, and your gem functions correctly in projects that do not load them already.
With both of these in mind, it is often quickest and easiest to require dependencies early and and in a way that can be quickly viewed. So the advice is sound; as it was presented in a very short article, covering the statement with caveats and extra background would make the whole thing a lot less pithy.
I'm beginning with the Ruby programming language and I'm interested in understanding it in depth before I start studding the Rails framework.
I'm currently a little disappointed because everybody seams to care only about the Rails framework, and other aspects of the language are just not discussed in depth, such as its class loading mechanism.
Considering that I'm starting by doing some desktop/console experiments, I would like to better understand the following matters:
Is it a good practice to place each Ruby class in a separate Ruby file? (*.rb)
If I have, let's say .. 10 classes .. and all of them reference each other, by instantiating one another and calling each other's methods, should I add a 'require' statement in each file to state which classes are required by the class in that file? (just like we do with 'import' statements in each Java class file?)
Is there a difference in placing a 'require' statement before or after (inside) a class declaration?
What could be considered a proper Ruby program's 'entry point'? It seams to me that any .rb script will suffice, since the language doesn't have a convention like C or Java where we always need a 'main' function of method.
Is class loading considered a 'phase' in the execution of a Ruby program? Are we supposed to load all the classes that are needed by the application right at the start?
Shouldn't the interpreter itself be responsible for finding and loading classes as we run the code that needs them? By searching the paths in the $LOAD_PATH variable, like Java does with its $CLASSPATH?
Thank you.
In general terms, it's a good practice to create a separate .rb file for each Ruby class unless the classes are of a utility nature and are too trivial to warrant separation. An instance of this would be a custom Exception derived class where putting it in a separate file would be more trouble than its worth.
Tradition holds that the name of the class and the filename are related. Where the class is called ExampleClass, the file is called example_class, the "underscored" version of same. There are occasions when you'll buck this convention, but so long as you're consistent about it there shouldn't be problems. The Rails ActiveSupport auto-loader will help you out a lot if you follow convention, so a lot of people follow this practice.
Likewise, you'll want to organize your application into folders like lib and bin to separate command-line scripts from back-end libraries. The command-line scripts do not usually have a .rb extension, whereas the libraries should.
When it comes to require, this should be used sparingly. If you structure your library files correctly they can all load automatically once you've called require on the top-level one. This is done with the autoload feature.
For example, lib/example_class.rb might look like:
class ExampleClass
class SpecialException < Exception
end
autoload(:Foo, 'example_class/foo')
# ...
end
You would organize other things under separate directories or files, like lib/example_class/foo.rb which could contain:
class ExampleClass::Foo
# ...
end
You can keep chaining autoloads all the way down. This has the advantage of only loading modules that are actually referenced.
Sometimes you'll want to defer a require to somewhere inside the class implementation. This is useful if you want to avoid loading in a heavy library unless a particular feature is used, where this feature is unlikely to be used under ordinary circumstances.
For example, you might not want to load the YAML library unless you're doing some debugging:
def debug_export_to_yaml
require 'yaml'
YAML.dump(some_stuff)
end
If you look at the structure of common Ruby gems, the "entry point" is often the top-level of your library or a utility script that includes this library. So for an example ExampleLibrary, your entry point would be lib/example_library.rb which would be structured to include the rest on demand. You might also have a script bin/library_tool that would do this for you.
As for when to load things, if there's a very high chance of something getting used, load it up front to pay the price early, so called "eager loading". If there's a low chance of it getting used, load it on demand, or leave it "lazy loaded" as it's called.
Have a look at the source of some simple but popular gems to get a sense of how most people structure their applications.
I'll try to help you with the first one:
Is it a good practice to place each Ruby class in a separate Ruby file? (*.rb)
It comes down to how closely related those classes are. Let's see a few examples. Look this class: https://github.com/resque/resque/blob/master/lib/resque.rb
, it "imports" the functionality of several classes that, although they work together, they are not closely related to be bundled together.
On the other hand, take a look at this module: https://github.com/resque/resque/blob/master/lib/resque/errors.rb. It bundles 5 different classes, but these do belong together since they are all essentially representing the same.
Additionally, from a design standpoint a good rule of thump could be asking yourself, who else is using this class/ functionality (meaning which other parts of the code base needs it)?
Let's say that you want to represent a Click and WheelScroll performed by a Mouse. It would make more sense in this trivial example, that those classes be bundled together:
module ComputerPart
class Mouse; end
class WheelScroll; end
class Click; end
end
Finally, I would recommend that you peruse the code of some of these popular projects to kind of get the feeling how the community usually make these decisions.
1.) I follow this practice, but it is not necessary, you can put a bunch of classes in one file if you want.
2.) If the classes are in the same file, no, they will all be accessible when you run the script. If they are in separate files then you should require them, you can also require the entire directory that the file(self) is in.
3.)Yes, it should be at the top of the file.
4.) In ruby everything descends from the Main object, the Interpreter just handles creating it for you. If you are writing OO ruby and not just scripts, then the entry point will be the init method of the first class you call.
5.) Yes, before the program runs it loads up all the dependencies.
6.) I think it does this, all you have to do is require the proper files at the top of the files, after that you can use them as you wish without having to implicitly load them again.
I've been looking at the Ruby Standard Library Documentation for 1.9.3. I'm wondering how I can find out which libraries I need to explicitly require.
For example, I have been told I need to explicitly require the json library, but not rubygems, although they both appear in the standard library list.
Is there another place I can look for information about the requirements, or even a pry/irb command I can run to see what is already 'required'?
Every library has to be required/loaded, if you want to use it.
Performance-wise, require is smart and will not load libraries if they're already loaded.
However, if you want to check if a library is required you should see the top-level namespace it defines and check if this is defined in your current scope. For example open an IRB session and do:
defined? JSON # => nil (it's not loaded)
require 'json' # => true (load it)
defined? JSON # => "constant" (it's loaded)
require 'json' # => false (it's already loaded, so it's not loaded it again)
It usually doesn't hurt to require things anyway. If they've already been loaded, in general terms, the require statement has no effect.
Some core library components are either loaded automatically or autoloaded by referencing their top-level symbol. This list varies from one version of Ruby to another.