How to automatically include Gem in the path? - ruby-on-rails

I have foo.gem and there is lib/foo.rb in there.
When I add gem to Gemfile it's foo.rb is automatically required in my path. But I need to include it automatically. Reason for this is I am making console extension and I want them to be available without me writing `include Foo'.
I am experimenting with
SOME_CLASS.send(:include, Foo)
But not sure what class to use to have it added to the path e.g. when I start console that is automatically included. Here are some mixins automatically included in console, I need mine to be there :) Thank you
irb(main):006:0> self.class.included_modules
=> [PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Dependencies::Loadable, Kernel]
P.S.
I can solve problem with initializer but I don't want to change project's code I just want to add gem and that it works.

You should use the Kernel module, which is included by Object. It's where private methods like exit, puts and require are defined, so it is an excellent choice for defining an imperative API.
When you extend Object, people expect to be able to call your methods explicitly on any object, and they also understand that your method depends on that object's state.
Kernel methods understood differently. Even though they're technically available to all objects, you don't expect people to write things like:
'some string'.sleep 1000
This makes no sense. sleep has nothing to do with the string; it doesn't depend on it in any way. It should only be called with an implicit receiver, as if the very concept of self didn't exist.
Making your methods private and extending Kernel instead helps you get that message across.
You can do that in foo.rb:
module Foo
# …
end
Some::Class.send :include, Foo
When you load or require some file, it is executed line by line. You can put arbitrary code anywhere in the file, even inside module and class definitions. You can take advantage of that in order to properly set up your library so that others don't have to.

Did you tried
Object.send(:include,Foo)
or
self.send(:include,Foo)
inside your console

Related

Using require/require_relative method in def initializer is ok?

I did not find the correct place to use the require method in any documentation. I understand that it is desirable to use the require method at the very beginning of the script, but is it possible and how correct is it to use the require method in the initializer class constructor?
Usually i make like this
require 'my_file'
how good is it to do the option below
class MyClass
def initialize
require 'my_file'
end
end
Read require method documentation
I did not find the correct place to use the require method in any documentation.
The "correct" place depends on your requirements and also on your coding style.
is it possible and how correct is it to use the require method in the initializer class constructor?
It is possible. Whether it is "correct" or not depends on your definition of "correct" and it depends on what you want to do.
require only does three things:
Search for a file in the load path.
Check whether the file was already run.
If it wasn't, run the file.
That's all require does.
If you require a file in the initializer, require will only run when you call the initializer (which is usually when you instantiate a new object).
If you need some functionality from the file before you instantiate an object, you are out of luck, since the require will not have run.
Also, you will run require every time you instantiate an object, but since require only runs the file once, that will simply be a waste of time, since it will still search for the file and check whether it was already run every time.
Lexically nesting a call to require like this can also be confusing. Someone who is not familiar with Ruby may assume that by requireing myfile inside the initialize method, the definitions inside my_file might be scoped purely to the initialize method, but that is obviously not the case: require simply runs the file, it does not perform any scoping. The definitions inside my_file will be defined wherever my_file says they are.
In the same vein, someone who is reviewing your code might assume that you think that this creates some sort of scoping and might now wonder whether your code has some sort of bug or (worse) security leak based on that assumption.
And note that "someone who is reviewing your code" might very well be yourself in two years, when you have no idea anymore why you wrote the code this way.
You can put it on top of the file before the class declaration. So you have:
require 'my_file'
class MyClass
def initialize
end
end
It's possible, it will work correctly, but it's highly unusual. I guarantee this will raise questions in code review.
Normally, requires are placed on top of the file.
Declaring the require "./file_name" is not recommended to use in the constructor method as it is often used to create the instance variable and particularly: if you are going to use an instance or global variable from that required file class as a parameter to the initialize (constructor) method of the current class, it may end up with an error.
You may use these ways to require the file at the top of the class:
require 'my_file'
class MyClass
def initialize
puts "this is a constructor"
end
end
or you may also require it just before calling your class is highly recommended to use require
class MyClass
def initialize
puts "this is a constructor"
end
end
require 'my_file'
object = MyClass.new
object.some_method
This allows you to use all the instance, class, method, object...etc.. in your current class.

Where does Rails include modules in a class from lib?

We have a Rails application. There is a class in lib called PriorityFilter. It's a simple PORO class. It doesn't explicitly inherit from other classes and it doesn't include any modules. However, if I run Rails console I can see that the class includes a number of modules:
irb(main):002:0> PriorityFilter.included_modules
=> [ActiveSupport::ToJsonWithActiveSupportEncoder, ActionView::Helpers::NumberHelper, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, Kernel]
The class is used in a view helper, to prepare data for rendering a template. If I place a debugger brake point in the view helper and check included modules, there are even more modules in the list:
(byebug) PriorityFilter.included_modules
[ActiveSupport::ToJsonWithActiveSupportEncoder, ActionView::Helpers::UrlHelper, ApplicationHelper, DateTimeHelper, Aligni::DateTimeFormatter, ActiveJob::TestHelper, UnitHelper, ActionView::Helpers::TextHelper, ActionView::Helpers::TagHelper, ActionView::Helpers::OutputSafetyHelper, ActionView::Helpers::CaptureHelper, ActionView::Helpers::SanitizeHelper, ActionView::Helpers::NumberHelper, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, Kernel]
Among them are some helpers, such as ApplicationHelper, DateTimeHelper and UnitHelper that are actually defined in the application code, not Rails.
We checked thoroughly and these helpers are not explicitly included in this class (or other similar classes) anywhere in our application code. Because of that, I suspect that Rails does that. The questions are:
Is it true that Rails does that for all classes in lib?
Where does Rails include those modules?
Are different modules included based on the context where a class is used? Is there a way to find out which modules will be included?
Is there a way to control the list of included modules, via some configuration option? (I understand that modules can be explicitly included and that they can be included/excluded in runtime with methods available on every object.)
Your class, unless specified otherwise, inherits from Object and the ActiveSupport adds its own extensions (also) to Object class, like here, with ActiveSupport::ToJsonWithActiveSupportEncoder for example:
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
end
so to answer your specific questions:
No, if you write class that inherits from BasicObject, none of it will be included, most probably.
In various places, I gave you one example, you can search for another ones.
No, it's based on inheritance chain.
No, as far as I know.
I'm not sure though, how are the helpers included. I'd try something like this to find it out, with the usage of included hook:
module ApplicationHelper
def self.included(base)
binding.pry # or any other debugger
end
end
And then I'd start the application and see the backtrace, maybe it would work.

Finding out where methods are defined in Ruby/Rails (as opposed to Java)

I am just getting started with Ruby on Rails. Coming from the Java world, one thing that I am wondering is how do Ruby/Rails developers find out where methods are actually defined.
I am used to just clicking on the method in Eclipse to find where is is defined even in third party libraries (supposing I have the source code).
A concrete example: I am trying to find out how the Authlogic gem apparently changes the constructor of my User class to require an additional parameter (called :password_confirmation) even though the User class doesn't even inherit from anything related to Authlogic.
Probably I am just overlooking something really obvious here (or maybe I still can't wrap my head around the whole "convention over configuration" thing ;-))
It's slightly difficult to quickly find the method location for dynamic languages like Ruby.
You can use object.methods or object.instance_methods to quickly find out the methods.
If you are using Ruby 1.9, you can do something like this:
object.method(:method_name).source_location
For more information on source_location - click here
The Pry gem is designed precisely for this kind of explorative use-case.
Pry is an interactive shell that lets you navigate your way around a program's source-code using shell-like commands such as cd and ls.
You can pull the documentation for any method you encounter and even view the source code, including the native C code in some cases (with the pry-doc plugin). You can even jump directly to the file/line where a particular method is defined with the edit-method command. The show-method and show-doc commands also display the precise location of the method they're acting on.
Watch the railscast screencast for more information.
Here are some examples below:
pry(main)> show-doc OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb # line 46:
Number of lines: 11
visibility: private
signature: initialize(hash=?)
Create a new OpenStruct object. The optional hash, if given, will
generate attributes and values. For example.
require 'ostruct'
hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)
p data # -> <OpenStruct country="Australia" population=20000000>
By default, the resulting OpenStruct object will have no attributes.
pry(main)>
You can also look up sourcecode with the show-method command:
pry(main)> show-method OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb # line 46:
Number of lines: 9
def initialize(hash=nil)
#table = {}
if hash
for k,v in hash
#table[k.to_sym] = v
new_ostruct_member(k)
end
end
end
pry(main)>
See http://pry.github.com for more information :)
None of people advising Pry gem mentionned the method called find-method, which is probably what author was looking for.
Here's the example:
pry(main)> find-method current_user
Devise::Controllers::Helpers
Devise::Controllers::Helpers#current_user
WebsocketRails::ConnectionAdapters::Base
WebsocketRails::ConnectionAdapters::Base#current_user_responds_to?
Then, you can browse the method code by following #banister's tips.
You could use something like pry. See its railscast also.
There are several ways to change an existing class. E.g. if you want to modify the String class write:
class String
def my_custom_method
puts "hello!"
end
end
But there are other options like mixing in modules or adding/modifying methods by using meta-programming.
Anyhow, having some object you can always:
puts obj.methods.inspect
Either do it in your code or use the debugger.
The other option is to read the code. In particular you should read the gem's unit tests (./spec, ...). There are quite a lot of authors stating that unit tests make documentation obsolete.
In Ruby you can also add both class and instance methods to a given class by using mixins.
Essentially if you have a module you can add its methods to a given class using both include and extend class methods. A brief example on how those works is the following
Module A
def foo
"foo"
end
end
Module B
def bar
"bar"
end
end
Class YourClass
include A
extend B
end
p YourClass.new.foo # gives "foo" because the foo method is added as instance method
p YourClass.bar # gives "baz" because the bar method is added as class method
Because Ruby is a dynamic language, these statements can be used everywhere. So to come to your question there is no need to extend an authlogic class to get its methods. Many plugins uses this instruction when loaded
ActiveRecord::Base.send :include, ModuleName
In this way they tell to every AR object to include some plugin defined module and you get all the methods in AR objects.
Another technique used by many acts_as plugins is to include their modules only when the acts_as call is used in the base class.
Other useful references
What is the difference between include and extend in Ruby?
A quick tutorial about mixins

Ruby on Rails: Learning ActionController class - Question on $:.unshift activesupport_path and autoload method

Inside ActionController class (rails/actionpack/lib/action_controller.lib) I found several weird code. I don't really have a mentor to learn Ruby on Rails from, so this forum is my only hope:
Question #1: Could anyone help me explain these lines of codes?
begin
require 'active_support'
rescue LoadError
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
if File.directory?(activesupport_path)
$:.unshift activesupport_path
require 'active_support'
end
end
Especially the line with $:.unshift activesupport_path
In my thought, it tries to require active_support class, and if that doesn't work, it looks if activesupport_path is a directory, if it is, then . . . I totally lost it.
Question #2: What autoload method is for?
module ActionController
# TODO: Review explicit to see if they will automatically be handled by
# the initilizer if they are really needed.
def self.load_all!
[Base, CGIHandler, CgiRequest, Request, Response, Http::Headers, UrlRewriter, UrlWriter]
end
autoload :Base, 'action_controller/base'
autoload :Benchmarking, 'action_controller/benchmarking'
autoload :Caching, 'action_controller/caching'
autoload :Cookies, 'action_controller/cookies'
.
.
.
Question #3: If I later find a method I don't understand what for, how is the best way to find out? As for that autoload method case, I tried to find it across my project (I have my Rails code frozen there) but couldn't find any clue. I searched for "def autoload". Am I doing things wrong? Is my IDE, TextMate just doesn't cut it?
Thank you!
In order for a file to be required you have to ensure that the path to it is in the Ruby $LOAD_PATH variable. This is has a short-hand version $: for legacy reasons, inheriting this from Perl.
When you call require, the interpreter looks for a .rb file in each of the paths given there until it finds a match. If it finds one, it is loaded. If not you get an exception.
Often you will see lines like this in files:
# script/something
# This appends "script/../lib" to the $LOAD_PATH, but this expands to
# something like "/home/user/project/lib" depending on the details of
# your installation.
$: << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
You can use standard Array modifiers on $LOAD_PATH like unshift, push, and <<.
The first block of code is attempting to load active_support and only if that fails does it go about modifying the $LOAD_PATH to include the likely location of this file based on the path to the file making the require call. They do this because typically all gems from the Rails bundle are installed in the same base directory.
The reason for using unshift is to put that path at the highest priority, inserted at the front of the list. The << or push method adds to the end, lowest priority.
When you require a file it is loaded in, parsed, and evaluated, an operation which can take a small but measurable amount of time and will consume more memory to hold any class or method definitions inside the file, as well as any data such as string constants that may be declared. Loading in every single element of a library like ActiveRecord using require will require a considerable amount of memory, and this will import every database driver available, not just the ones that are actually used.
Ruby allows you to declare a class and a path to the file where it is defined, but with the advantage of not actually loading it in at that moment. This means that references to that class don't cause script errors in other parts of your application that make use of them.
You will often see declarations like this:
class Foo
# Declare the class Foo::Bar to be defined in foo/bar.rb
autoload(:Bar, 'foo/bar')
end
When using autoload you need to keep in mind that the class name is always defined within the scope of the module or class declaring it. In this example Bar is within Foo, or Foo::Bar using Ruby naming conventions.
When you make use of the Bar class, the foo/bar.rb file will be required. Think of it as creating a stub Bar class that transforms into the real class once it's actually exercised.
This is a great way of keeping a lot of options open, with many different modules ready to use, but without having to load everything into memory up front.
As for the third question, searchable documentation like APIDock will help you try and find more information on methods. The distinction between Ruby and Rails is often blurred, so you may have to check through both to be sure. Rails adds a lot of methods to core Ruby classes, so don't take the listing of methods available to be complete on either side. They work in conjunction.
Sometimes it pays to search for def methodname when trying to find out about where methodname originates, although this covers only conventional declarations. That method may be an alias from a mechanism like method_alias or may have been dynamically created using define_method, you can never really be sure until you dig around. At least 90% of the methods in Rails are declared the conventional way, though, so most of the time a simple search will yield what you want.

When to call a "require" in Rails?

I have a more conceptual question in Rails... or Ruby for that matter:
Is it best to call a require right before the method that needs it, group my requires at the beginning of the class or somewhere in an initializer when Rails boots?
Does it matter from a performance point of view? From a readability point of view? Does it make a difference if I'm using Rails 3?
Thanks!
If you're concerned about performance then you should require things in the context of where they are needed so that if that portion of your code is not exercised, the library is not loaded. Any subsequent calls to require have no effect as that file has already been loaded. This ends up looking like something along the lines of:
if (user.using_openid?)
require 'openid'
# ... Do OpenID stuff
end
While this is more efficient in terms of resources, it can make it very difficult to determine the dependencies of your application. Declaring these up-front makes it clear to other people maintaining the software. Keep in mind that "other people" always includes your future self when you've forgotten about some details of your application.
You're technically allowed to require anything at any time, late or early, but declaring your requirements up front is better from a design perspective. If you find that there is an element that is used only intermittently and takes an unusual amount of time or memory to load, then you should probably document that up front in your requirements file. For example:
require 'library1'
require 'library2'
require 'library3'
require 'library4'
require 'library5'
# Other libraries loaded as required:
# * slowimagelibrary
# * slowencryptionlibrary
# * openid
Arguably this is less of an issue with bundler because you can have your gems declared up front more formally and the actual require call can come later.
If you consider vanilla Ruby, 'require' is mostly used in the first lines, because you then are sure you have access to what you need, and it is easier to find and read what dependency you need.
There are a few cases when you want to load a gem only in a method, because this is not really needed for your script to work (e.g.: a optional visualization).
With Rails, I believe it depends on what you want to do.
If you use Bundler, you can assume your gem has been 'required' (you can of course override what is required with the :require option).
If it is some stuff you want to autoload when the server start (like validators or form builders), then you should look how to do with the config (autoload_paths and eager_load_paths).
require can also be used to load only a part of a gem, like an extension to it. Then it is of course required where the configuration is.
You might be concerned if you work in a multi-threaded environment, as they are some problems with that. You must then ensure everything is loaded before having your threads running. (Something like the class constant is loaded, but the methods not yet, there was a good article but I can not find it anymore).
You might also want to try {Module,Kernel}.autoload, Rails extensively use it to load only what is necessary when accessed (but it looks rather ugly).
You can also hack it yourself with const_missing (so this can do plain lazy-loading, if you accept a structure).
This is a simple example (will not be appropriate for nested classes).
def Object.const_missing c
if (file = Dir["#{c.downcase}.rb"]).size == 1
require_relative(file)
end
if const_defined? c
const_get c
else
super # Object < Module
end
end
About performance, a call to require is relatively expensive, so if you know you are going to use it, do it only once if possible. However, to manage complex dependencies within your project, you might need to require relative files. Then require_relative is the way to go in 1.9.
Lastly, for a project, I would recommend to require all in the main file in lib/, with some Dir["**/*.rb"] expression. You would then rarely need to require_relative, because it is only needed if you reference in the body of the class another constant (all the contents of the methods are not resolved, so there is no problem with that).
Another solution would be to define these constants in your main file, it would also give you an idea of the structure.

Resources