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.
Related
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.
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.
I'm using Netbeans to program in Ruby and I can't seem to access other classes I write from the main class in Ruby until I place that code inside the main class itself. Is there a way to fix this so that it works like Java classes do?
If I understand you correctly, you are looking to import a class you wrote in a separate file into your current file. If this is what you are looking to do, take a look at require_relative
# cow.rb
class Cow
def moo
'Moooooooo'
end
end
# main.rb
require_relative 'cow.rb'
milford = Cow.new
puts milford.moo #=> 'Moooooooo'
Things to look out for is that require_relative searches for the file in the current location of the file you call it in. For instance:
# If cow.rb is in folder 'animals'
require_relative 'animals/cow.rb' #=> Fine
require_relative 'cow.rb' #=> LoadError
I would suggest finding some good tutorials on Ruby or finding a beginners book. Some of them are even available online like Programming Ruby The Pragmatic Programmer's Guide. This question covers some pretty basic Ruby concepts.
Also, I would not suggest using Netbeans since they cut out their support for Ruby. This is fine if you want to continue to use the old version of Netbeans but you will soon find it lacking support for newer Ruby versions.
For one thing, Ruby has no concept of "packages". There are files, and modules. To import all of the global variables, constants, modules, and classes from a file in the same directory, type:
require_relative "myfile.rb"
You can now use any classes, modules, constants, and global variables defined in myfile.rb in your code.
I need some insight into the construction of Ruby programs. I'm trying to learn how to write Ruby (independent of Rails) so I'm translating some Perl scripts I wrote in a bioinformtatics project into Ruby code. Basically creating classes where useful and whatnot.
My issue is how do I execute it? The Perl scripts are just long blocks of commands, one after the other. What's appropriate in Ruby? Should I define my classes in their own .rb files and call those and their methods in a sepearate rb file that sort of uses them to execute my program?
What is normally done? Any examples would be greatly apreciated. I'd also appreciate any tips in general on how to go about learning this kind of thing.
Ruby does have what's usually called the top level execution environment, and so a long string of commands will execute immediately just like Perl. Or, you can define classes and modules and go all OOP on your problem if you want, or you can mix the approaches.
You will need at least one line at the top level or top level of a class to start everything off. So:
p :hello
or
class A
p :hello
end
or
class A
def run
p :hello
end
end
A.new.run
or, my favorite:
class A
def run
p :hello
end
self
end.new.run
I'd highly recommend looking at some of your other favorite gems to see how their code is structured (like on Github). That's how I found my start. Thinking of your project as a "gem", being released or not, is a good way to wrap your mind around the problem.
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.