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.
Related
When I have the following ruby code
#file a.rb
class A
puts '2'
end
if I execute rb a.rb I get 2 printed onto the screen. This is because of the way ruby interprets the code, but, what is the name of this behavior?
The reason it prints something is because in the course of defining class A you asked it to. Anything inside a class block is treated as regular Ruby code, it's not special, so printing, exiting, making network connections, opening files, that all works as it would anywhere else.
This is in stark contrast to things like JavaScript and C++ where that is absolutely not allowed.
Ruby, being a dynamic programming language, has a lot more latitude. This permits things like defining methods based on input from files, or pretty much anything you can imagine.
The name of this behaviour is basically "evaluation", as in when Ruby evaluates that code, that is it parses and runs it.
This allows you to do things in Ruby not possible in other languages without employing macros, pre-processor tricks, or other techniques:
class A
if (Date.today.saturday? or Date.today.sunday?)
def party!
:on
end
end
end
Where that will only define the party! method when the code is run on a weekend.
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.
I've developed a set of Ruby scripts. Each of them should be 'self-contained', so a user can run it on its own. But also I would like to use them to build other scripts, I mean for example to use its methods but also to run it as a whole, without doing ` script.rb`.
So far what I have is just a couple of scripts (separate files) where I have no classes, just a couple of methods. The processing of taking user input and running those methods is outside of any functions. I see that this model may be not right.
My question is, what should I do now to keep every script self contained but also to allow other scripts to use it? Should every script just contain a class with a main method that I would run object.main?
Or maybe my approach of writing a simple scripts, no classes is also good?
If I start a new script, should I always go the objective way?
When I write a one off script, I often wrap it in a class. You've pointed out some advantages of doing this including reuse and cleaner documentation.
I find that there are several levels of polish for scripts depending on how they are going to be used. If the script is run once and never used again, I may not wrap it in a class. If it's important (taking backups of production systems), it's probably worth putting it in full gem form and writing tests. Somewhere in the middle is the single purpose class. Generally this means you're taking the code that's not in a method and putting it in the class constructor.
This:
#!ruby
def amethod(i)
i+1
end
ARGF.each do |l|
if l.chomp.to_i > 0
puts amethod(l.chomp.to_i)
end
end
Becomes:
#!ruby
class OneAdder
def amethod(i)
i+1
end
def initialize
ARGF.each do |l|
if l.chomp.to_i > 0
puts amethod(l.chomp.to_i)
end
end
end
end
OneAdder.new
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
Steve Klabnik recently said in a pull request for a utility module:
[The code] obscures the fact that these are class methods, and we
want to use them that way. Plus, I think that extend self is generally
an anti-pattern, and shouldn't really be used except in some cases. I
thought about it, and I think this is one of those cases.
When creating a utility module (e.g., for math) what's the best way to declare the methods?
And when is the extend self idiom ever appropriate?
It's not exactly helpful that he doesn't say 1) why he thinks it is an anti-pattern (other than obscuring the fact that you are defining class methods) or 2) why, having thought about it, this is one of the cases he thinks it shouldn't be used, so it's hard to specifically counter any of his arguments.
However, I'm not convinced that extend self is an anti-pattern. A utility module seems like a good example of a use case for it. I've also used it as easy storage for test fixtures.
I think it's worth examining what extend self is, what possible problems there might be with it, and what alternatives there are.
At it's core, it is simply a way to avoid having to write self. before every method definition in a module that you never intend to mix into a class, and that will therefore never have an 'instance' of itself created, so can by definition only have 'class' methods (if you want to be able to call them, that is).
Does it disguise the fact that you intend the methods to be used as class methods? Well, yes, if you don't look at the top of the file to where it says extend self, that's possible. However, I would argue that if it's possible for you to make this confusion, your class is probably too complicated anyway.
It should be obvious from your class - from its name and from its contents - that it is intended as a collection of utility functions. Ideally it wouldn't be much more than a screen tall anyway, so extend self would almost never be out of sight. And as we'll see, the alternatives also suffer almost exactly the same problem.
One alternative would be to use class << self like this:
module Utility
class << self
def utility_function1
end
def utility_function2
end
end
end
I am not a fan of this, not least because it introduces an extra layer of indentation. It's also ugly (totally subjective, I know). It also suffers from exactly the same problem of 'obscuring' the fact that you're defining class methods.
You're also free, using this approach, to define instance methods outside the class << self block - which might lead to the temptation to do so (although I'd hope it wouldn't), so I'd argue that extend self is superior in this regard by removing the possibility of this muddying of the waters.
(The same is true, of course, of the 'long-hand' style of using def self.utility_function.)
Another approach could be to use a singleton object. I don't think this is a good idea at all, because a singleton object is an object for a reason - it's meant to hold state and do stuff, but also be the only one in existence. That simply doesn't make sense for a utility module, which should be a series of independent stateless functions. You don't want MathUtils.cos(90) to ever return a different value based on internal state of MathUtils, right? (I know that you can of course hold state in a module and do all these things, but it's more of a semantic division for me than a technical one).
It also leads to the same problem of arguably obscuring the fact that the methods are intended to be called as class methods (sort of). They are defined as instance methods, and you call them as instance methods, but by first getting the single instance of the class by calling the class method instance.
class MathSingleton
include Singleton
def cos x
end
end
MathSingleton.instance.cos x
This would be a terrible alternative to extend self for this purpose. But look, also, the only thing indicating that these methods are to be used as methods on the singleton instance is that one line just up at the top, just like extend self.
So what other possible downsides are there? I don't know of any, but I'd be interested to hear them if anyone else does.
I would argue that extend self leads to shorter code, that leaves out the extraneous self.s and allows you to concentrate on the names and therefore meanings of its methods.
It also has the nice property that, if you are writing another class that uses lots of your utility functions, for example, you can just mix it in and they will be available without having to use the module name each time. Much like static imports work in other languages.
Utility modules, as opposed to mixins, are containers that wrap constants and methods with some common concern. Mixins, such as this one,
module SingingCapability
def sing; puts "I'm singing!" end
end
Human = Class.new
Fred = Human.new.tap { |o| o.extend SingingCapability }
generally pose some requirements on their includers. That is, generally only certain objects are good candidates to include or extend a given mixin. Hypothetically, it is possible that a module is at the same time a utility module, and a mixin. And if the module itself belongs among eligible candidates to be extended by it, then go ahead and extend it.
In sum, I do think it's somewhat not a very good practice, but Ruby defies me on this one since we even have Module#module_function method to facilitate this malpractice:
module SingingBox
def sing; "Tralala!" end
module_function :sing
end
SingingBox.sing #=> "Tralala!"
Is there a difference between the following 2 snippets of code?
# 1st snippet
class A
class B
# some code here
end
end
# 2nd snippet
class A::B
# some code here
end
If there is a difference, can you help me understand what the difference is and why you would use one version versus the other?
This seems to be mostly syntactic sugar for organizing your code - whichever way makes sense to you is the "correct" way. The only exception is that with the 2nd snippet, if class A hasn't already been defined you'll get an error. For the most part this question is a duplicate of this one, though since you are nesting classes in classes instead of classes in a module, I'll go ahead and link the Module docs, which explains the difference between modules and classes in Ruby and may help you interpret that SO answer in the context of your own question.