That's all, i want to see what are the clases that inherits a fixed class. There is a method for this in Ruby?
Aptana offers an option that shows this, but is there any method?
Thanks
Are you asking to see all the ancestors of a class, or the descendants? For ancestors, use:
Class.ancestors
There is no comparable method "out of the box" for descendants, however. You can use ObjectSpace, as below, but it's slow and may not be portable across Ruby implementations:
ObjectSpace.each_object(Class) do |klass|
p klass if klass < StandardError
end
EDIT:
One can also use the Class#inherited hook to track subclassing. This won't catch any subclasses created before the tracking functionality is defined, however, so it may not fit your use case. If you need to use that information programmatically on classes defined inside your application, however, this may be the way to go.
Module#ancestors
Example:
class Foo
end
class Bar < Foo
end
Bar.ancestors # => [Bar, Foo, Object, Kernel]
Related
I've been googling around for this and haven't been able to find an answer, which makes me think the answer is no, but I figured I'd ask here in case anyone knows for sure.
Does Ruby have a hook for when methods are defined (ie on a module or class)?
If not, is anyone familiar enough with the implementation of the main object to know how exactly it copies methods to Object when they're defined at the top level?
Really curious about this. Thanks for any info :)
It does. Module#method_added https://ruby-doc.org/core-2.2.2/Module.html#method-i-method_added
module Thing
def self.method_added(method_name)
puts "Thing added #{method_name}"
end
def self.a_class_method; end
def do_something; end
end
class Person
def self.method_added(method_name)
puts "I added #{method_name}"
end
attr_accessor :name
end
Thing
Person.new
# Thing added do_something
# I added name
# I added name=
If not, is anyone familiar enough with the implementation of the main object to know how exactly it copies methods to Object when they're defined at the top level?
It doesn't "copy methods". The language specification simply says that methods defined at the top-level become methods of Object. This is exactly the same mechanism as the one that says that methods defined inside class Foo become methods of class Foo. The language spec says it, therefore the implementors implement it that way. main doesn't need to do anything.
If you want to get real technical, then this is about the default definee, which is the implicit scope in which methods get defined when you don't explicitly specify the definee (as in def foo.bar; end). Usually, the default definee is the self of the closest lexically enclosing class or module definition body, and when there is no lexically enclosing class or module definition, it is Object. But some reflective methods, such as instance_eval or class_eval etc. may or may not change it.
Currently reading a Ruby style guide and I came across an example:
def no_op; end
What is the purpose of empty body methods?
There are a number of reasons you might create an empty method:
Stub a method that you will fill in later.
Stub a method that a descendant class will override.
Ensure a class or object will #respond_to? a method without necessarily doing anything other than returning nil.
Undefine an inherited method's behavior while still allowing it to #respond_to? the message, as opposed to using undef foo on public methods and surprising callers.
There are possibly other reasons, too, but those are the ones that leapt to mind. Your mileage may vary.
There may be several reasons.
One case is when a class is expected to implement a specific interface (virtually speaking, given that in Ruby there are no interfaces), but in that specific class that method would not make sense. In this case, the method is left for consistency.
class Foo
def say
"foo"
end
end
class Bar
def say
"bar"
end
end
class Null
def say
end
end
In other cases, it is left as a temporary placeholder or reminder.
There are also cases where the method is left blank on purpose, as a hook for developers using that library. The method it is called somewhere at runtime, and developers using that library can override the blank method in order to execute some custom callback. This approach was used in the past by some Rails libraries.
Is it possible to code something that can tell me when a Ruby class is defined?
Yes!
class Object
def self.inherited(base)
puts "#{base} inherited from object"
end
end
class Animal
end
class Cat < Animal
end
Running the above code prints the following:
Animal inherited from object
Cat inherited from object
Basically, the self.inherited callback is triggered whenever a class is defined that inherits from the class it is defined on. Put it on Object and that's any class! (Although there may be some special case exceptions I can't think of just now).
I should probably add the disclaimer that, while it is possible to do this (because of just how awesome Ruby is as a language), whether it is advisable to do this, especially in code destined for production use, I'm not so sure. Well, actually, I am sure. It would be a bad idea.
Let's say I have a bunch of related functions that have no persistent state, say various operations in a string differencing package. I can either define them in a class or module (using self) and they can be accessed the exact same way:
class Diff
def self.diff ...
def self.patch ...
end
or
module Diff
def self.diff ...
def self.patch ...
end
I can then do Diff.patch(...). Which is 'better' (or 'correct')?
The main reason I need to group them up is namespace issues, common function names are all used elsewhere.
Edit: Changed example from matrix to diff. Matrix is a terrible example as it does have state and everyone started explaining why it's better to write them as methods rather than answer the actual question. :(
In your two examples, you are not actually defining methods in a Class or a Module; you are defining singleton methods on an object which happens to be a Class or a Module, but could be just about any object. Here's an example with a String:
Diff = "Use me to access really cool methods"
def Diff.patch
# ...
end
You can do any of these and that will work, but the best way to group related methods is in a Module as normal instance methods (i.e. without self.):
module Diff
extend self # This makes the instance methods available to the Diff module itself
def diff ... # no self.
def patch ...
end
Now you can:
use this functionality from within any Class (with include Diff) or from any object (with extend Diff)
an example of this use is the extend self line which makes it possible to call Diff.patch.
even use these methods in the global namespace
For example, in irb:
class Foo
include Diff
end
Foo.new.patch # => calls the patch method
Diff.patch # => also calls Diff.patch
include Diff # => now you can call methods directly:
patch # => also calls the patch method
Note: the extend self will "modify" the Diff module object itself but it won't have any effect on inclusions of the module. Same thing happens for a def self.foo, the foo won't be available to any class including it. In short, only instance methods of Diff are imported with an include (or an extend), not the singleton methods. Only subclassing a class will provide inheritance of both instance and singleton methods.
When you actually want the inclusion of a module to provide both instance methods and singleton methods, it's not completely easy. You have to use the self.included hook:
module Foo
def some_instance_method; end
module ClassMethods
def some_singleton_method; end
end
def self.included(base)
base.send :extend, ClassMethods
end
def self.will_not_be_included_in_any_way; end
end
class Bar
include Foo
end
# Bar has now instance methods:
Bar.new.some_instance_method # => nil
# and singleton methods:
Bar.some_singleton_method # => nil
The main difference between modules and classes is that you can not instantiate a module; you can't do obj = MyModule.new. The assumption of your question is that you don't want to instantiate anything, so I recommend just using a module.
Still you should reconsider your approach: rather than using arrays of arrays or whatever you are doing to represent a Matrix, it would be more elegant to make your own class to represent a matrix, or find a good class that someone else has already written.
Ruby Modules are used to specify behaviour, pieces of related functionality.
Ruby Classes are used to specify both state and behaviour, a singular entity.
There is a maxim in software design that says that code is a liability, so use the less code possible. In the case of Ruby, the difference in code lines is cero. So you can use either way (if you don't need to save state)
If you want to be a purist, then use a Module, since you won't be using the State functionality. But I wouldn't say that using a class is wrong.
As a trivia info: In Ruby a Class is a kind of Module.
http://www.ruby-doc.org/core-1.9.3/Class.html
The following also works
Matrix = Object.new
def Matrix.add ...
def Matrix.equals ...
That's because so-called "class methods" are just methods added to a single object, and it doesn't really matter what that object class is.
As a matter of form, the Module is more correct. You can still create instances of the class, even if it has only class methods. You can think of a module here as a static class of C# or Java. Classes also always have the instance related methods (new, allocate, etc.). Use the Module. Class methods usually have something to do with objects (creating them, manipulating them).
Is it possible to remove some of the inherited methods in Ruby? I mean, I can override it, but is there any other way?
Class ABC
end
a = ABC.new
puts a.id
Here, the method id is inherited from Object along with other methods like tap,class,type etc. I want to remove such methods.
Edit: I'm using Ruby 1.8.7
Yes - undef_method :foo will prevent any calls to the method foo (contrasted with remove_method :foo, which removes the method from the child, but still passes through up the inheritance chain).
Once again, though, why do you want to remove things like id?
You can always create a blank slate class to derive from:
class BlankSlate
instance_methods.each do |m|
undef_method(m) unless (m.match(/^__/))
end
end
This should strip out all methods except for the internal ones that you're not supposed to mess with, like __send__.
As tadman said you can make a BlankSlate object, or in ruby 1.9, there is the BasicObject class that has a bare minimum of methods. A quick google search turned up this for further reading: http://www.humbug.in/docs/ruby-best-practices/I_sect13_d1e2654.html
It appears that Rails already has BlankSlate built in: http://rubydoc.info/docs/rails/2.3.8/BlankSlate