Which context should I code for using "require" method [duplicate] - ruby

This question already has answers here:
Do Ruby 'require' statements go inside or outside the class definition?
(7 answers)
Closed 5 years ago.
The programs below have the same behavior. What does require do in fact?
In both cases, I can use methods which are defined in my_extension.rb. But, which is better in ruby?
case1: use requre in class.
class Foo
require "my_extension"
end
case2: use require in toplevel.
require "my_extension"
class Foo
end

Case 2 is better, purely because it's proper etiquette and easier for other programs to find your code's dependencies.
Technically, require does the exact same thing no matter where you call it: it simply runs the code in the file. The only difference between placements is when (if ever) the require is actually called. For example:
def my_method
require "my_extension"
end
In this case, my_extension.rb isn't loaded until my_method is called.

Related

Guard Ruby classes with class-level metaprogramming against multiple loads

A quirk of Ruby's require is that, while in general, it will only load a file once, if that file is accessible via multiple paths (e.g. symlinks), it can be required multiple times. This causes problems when there are things like class-level metaprogramming, or in general a code that should only be executed once on file loading, getting executed multiple times.
Is there any way, from inside a Ruby class definition, to tell whether the class has been defined before? I thought defined? or Object.const_get might tell me, but from those it looks like the class is defined as soon as it's opened.
This is not an answer to your question in the second paragraph, but a solution to the issue in your first paragraph. Actually, you cannot avoid multiple file loads by checking whether a class was defined already.
Instead of doing:
require some_file_name
do:
require File.realpath(some_file_name)
By doing so, different symbolic links pointing to the same real file would be normalized to the same real file name, and hence multiple loading of them would be correctly filtered by require.
Cf. this question and the answer given there.
The real solution is that requiring that a piece of code is only executed once is bad design and you should fix that.
However, what you could do is simply set some flag that the code has already been executed and check that flag. E.g.:
class Foo
unless #__executed__
def bla; end
puts 'Test'
end
#__executed__ = true
end

Namespacing in Ruby require

Suppose I have a module, mod.rb
# mod.rb
def foo
puts 'it'
end
And in another ruby file, main.rb I require it and use the function foo.
# main.rb
require('mod')
foo
When requiring multiple modules, this can make code hard to read because I don't really know where 'foo' is coming from. Is there any idiomatic way to namespace these things in Ruby for the purpose of readability? I am new to the language, and contributing to a project. It took a lot of investigative work to find out which methods came from where. If I wanted to contribute more by improving the readability, what would be a good approach?
You will want to wrap your code in an actual module or class
something like
class Foo
def self.bar
"quxx"
end
end
This way, you will be able to call Foo.bar to access your method.

Code placed outside of a method [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
In Java, every instruction executed is defined inside a method. In Ruby, you can do something like this:
class A
puts "Inside of A class" # [1]
end
and [1] will be executed when A is loaded. An example of this is the following code in Rails:
class Product < ActiveRecord::Base
validates :title, :presence => true, length: 1..19, :uniqueness => true
end
What sense does it have to write code outside of a method? How can it be used (how can it be invoked)?
I assume you want to know why you'd place code to execute "inside a class," when there's no way to have it execute more than once (when the class is first loaded.)
In Ruby, all classes are themselves objects - they are instance of the class Class. So what's happening under the hood when Ruby "reads" a class definition, is that Ruby is actually running methods on that instance of the class Class.
So a def inside the class definition of the class A is actually the same as A.send(:define_method, ...) - to understand what that means, you have to understand what senders and receivers are, and how they are implemented in Ruby. That SO post I linked to does a pretty good job of referring you to more material. The def syntax is just a convention to make the sending/receiving look like the syntax of other languages so that it's easier to "transition" to Ruby from other languages.
Ruby doesn't require that you should only call methods on the class itself when defining the class - so you can run any code you want. One use case is when you define a variable prefixed with an # inside the class definition:
class A
#class_var=123
def self.class_var
#class_var
end
def self.class_var=(inp)
#class_var=inp
end
end
a=A.new
b=A.new
b.class.class_var=5
puts a.class.class_var
# 5
Note the def self. notation that defines "class methods" - they can then access the "class variable" that you created by writing the code "inside the class."
This question comes up a lot for me, so I've written a more extensive blog post about it, to try and go into more detail about how Ruby implements these concepts. I have written them here in scare quotes, because they mean slightly different things in Java and C++, so don't apply their meanings very directly to try and understand what they mean in Ruby.
What sense has write code out of methods?
You've already seen it. Instead of changing the language itself (and the compiler) to add annotations to Ruby, the makers of Rails could make model validations easily (and lots of DSL for different things). Another example is att_accessor, a method that called in the context of a class will add accessor methods. And there are many many more.
Basically, you are adding that way lots of flexibility to the language.
How it can be used (how can it be invoked)?
You already did in your example. Just put the code there... and it is executed.
You can use and invoke it like such:
def putString
puts "Inside method outside of class"
end
class A
puts "Inside of A class" #[1]
putString
end
It gets invoked when you require the file.
Uses?
Meta-programming is one
['foo','bar'].each |m| do
def m
[m]
end
end
There's an even sneakier scenario where you can put code outside of the class, never mind the method, confused the heck out me when I first saw it.
Most of the answers here refer to code inside a class and outside its methods. I think the OP asked about code outside everything - forbidden in Java!
Java mimics the C languages' compilation cycle. In C, only certain kinds of lines can happen during compilation. Then, only the remaining kinds of lines can run during execution.
In Ruby, code evaluates from top to bottom. The commands class and def essentially mean "capture all these tokens, and evaluate them later." So, because the entire file evaluates at runtime, things outside classes can happen very early.
The most notorious example is:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require is (prepare for a shock) just a method, and File is (prepare for another one) always available. So a Ruby programmer can exchange zillions of boring, fragile lines of configuration files (in Java ANT or C MAKE) for just a few ugly - but bullet-proof - lines of raw Ruby, at the top of each file.

In Ruby, do i require within a class or outside?

If i want to make a class :
class Foo
#methods here
end
that requires lets say FileUtils
do i do
require 'fileutils'
class Foo
#methods here
end
or
class Foo
require 'fileutils'
#methods here
end
To complement fotanus's answer. Anything defined on a separate file rests in the main namespace, wherever you load or require it from. It does not make difference in terms of scope or namespace. Furthermore, local variables cannot be referenced across files.
So your choice should depend on maintainability. If you write the dependencies on the top of the file, it is easy to know the dependency at a glance. On the other hand, if you require within a certain module, it can make it clear that that dependency is only for the particular module. In the older days, I think the former was preferred, but nowadays, where people use the bundler gem, there is a means to see all the dependencies at a glance, so the motivation for the former may have declined.
It will work either way. require works anywhere, and the FileUtils will be available inside and outside of your class.
By what I have seen on github, it is usually on top - just like most of the other languages, by the way.

Ruby, including module in current directory

I am currently working through the Well Grounded Rubyist. Great book so far. I am stuck on something I don't quite get with ruby. I have two files
In ModuleTester.rb
class ModuleTester
include MyFirstModule
end
mt = ModuleTester.new
mt.say_hello
In MyFirstModule.rb
module MyFirstModule
def say_hello
puts "hello"
end
end
When I run 'ruby ModuleTester.rb', I get the following message:
ModuleTester.rb:2:in <class:ModuleTester>': uninitialized constant ModuleTester::MyFirstModule (NameError)
from ModuleTester.rb:1:in'
From what I have found online, the current directory isn't in the the namespace, so it can't see the file. But, the include statement doesn't take a string to let me give the path. Since the include statement and require statements do different things, I am absolutely lost
as to how to get the include statement to recognize the module. I looked through other questions, but they all seem to be using the require statement. Any hints are greatly appreciated.
You use require to load a file, not include. :-)
First, you have to require the file containing the module you want to include. Then you can include the module.
If you're using Rails, it has some magic to automagically require the right file first. But otherwise, you have to do it yourself.
You need to require the file before you can use types defined in it. *
# my_first_module.rb
module MyFirstModule
def say_hello
puts 'hello'
end
end
Note the require at the beginning of the following:
# module_tester.rb
require 'my_first_module'
class ModuleTester
include MyFirstModule
end
mt = ModuleTester.new
mt.say_hello
The require method actually loads and executes the script specified, using the Ruby VM's load path ($: or $LOAD_PATH) to find it when the argument is not an absolute path.
The include method, on the other hand actually mixes in a Module's methods into the current class. It's closely related to extend. The Well Grounded Rubyist does a great job of covering all this, though, so I encourage you to continue plugging through it.
See the #require, #include and #extend docs for more information.
* Things work a bit differently when using Rubygems and/or Bundler, but getting into those details is likely to confuse you more than it's worth at this point.

Resources