Ruby methods without class? - ruby

Hey everyone! I was wondering how the methods in Ruby that aren't called with the syntax ClassName.method_name work. Some off the top of my head are puts, print, gets, chomp. These methods can be called without using the dot operator. Why is this? Where do they come from? And how can I see the full list of such methods?

All methods in Kernel will be available to all objects of class Object or any class derived from Object. You can use Kernel.instance_methods to list them.

They come from the Kernel module that is automatically included for each class. Those
irb(main):001:0> class Foo
irb(main):002:1> end
=> nil
irb(main):003:0> Foo.included_modules
=> [Kernel]

Related

Using the Class itself as a Method

Today I came across the Pathname class in Ruby and noticed that you could directly call the class itself as a method (which would basically return a new instance):
Pathname("some/path")
# => #<Pathname:some/path>
I've been trying to replicate the same thing with my CustomClass but haven't been successful. I don't know what these methods are called and I can't find any Ruby code that gives me an idea on how to do this. My Question is how do I use the Class name as method?
Things I've tried so far:
Defining self.self()
Defining self.class()
Using the class << self syntax
Googling - But it just returns comparisons of class methods vs instance methods
This isn't using the class itself. This is calling a method in Kernel with the same name as the class. It's generally discouraged to do it yourself as you pollute almost all objects with new methods and leads to confusion (as you already see).
Here is the documentation for the method. There are a few others like Array, Hash, String, etc.
What you're looking for is a conversion method to coerce the input to the instance of the class.
It is not a method of the class itself, but a method in Kernel module. So in order to be able to use the form of MyClass(value) you should add the method to Kernel module:
module Kernel
def Foo(value)
# you can implement any logic here
value.is_a?(Foo) ? value : Foo.new(value)
end
module_function :Foo
end
class Foo
def initialize(bar)
#bar = bar
end
end
baz = Foo('bar')
#=> #<Foo:0x007fd4e5070370 #bar="bar">
Foo(baz)
#=> #<Foo:0x007fd4e5070370 #bar="bar">
baz == Foo(baz)
#=> true
This is not a class call, but a shortcut. And the trickiest part - it was defined for a Kernel module to be available everywhere in the form as you just specified.
Please proceed to the link of the official docs. There you can see, that requiring a Pathname module, it extend Kernel module to add the method of the same name.
To be honest, I strongly recommend against extending Kernel with your own method. Or at least to use refinements

Ruby Include Module in IRB

I'm working through Zed Shaw's Learn Ruby The Hard Way and I'm having an issue including a module in IRB. In exercise 25, we define a new module Ex25, require it in IRB, and then can use its various methods through the namespace of that module, e.g. Ex25.break_words(sentence). In the Extra Credit, it's stated that typing include Ex25 will basically add the methods from the module into the current "space" (not sure what to call it) and you can then call them without explicitly referring to the module, e.g. break_words(sentence). When I do this, however, I'm getting an "undefined method" error. Any help / explanation would be greatly appreciated, thanks!
That's an error in the book. The methods in Ex25 are class methods. include adds instance methods to the "current space." Remove self from the method definitions and it'll work:
module Ex25
def break_words(stuff)
stuff.split(' ')
end
end
include Ex25
break_words 'hi there' # => ["hi", "there"]
If you're curious, here's some more detail about what's going on: The place where the methods are included—the "current space"—is the Object class:
Object.included_modules # => [Ex25, Kernel]
All Object instances gain the included methods ...
Object.new.break_words 'how are you?' # => ["how", "are", "you?"]
... and the top-level is just an Object instance:
self.class # => Object
But wait. If the top-level is an Object instance, why does it respond to include? Isn't include an instance method of Module (and its subclass, Class)? The answer is that the top-level has a singleton method ...
singleton_methods.include? "include" # => true
... which we can assume forwards to the Object class.

Ruby - remove inherited methods

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

How is Ruby fully Object Oriented?

So, I'm curious as to how Ruby is a fully object oriented language. I stumble over one problem that isn't really clear to me.
If I define a function as follows
def foo(text)
print text
end
and I define the function outside of a class, how is this function an object? I realize that I can call
foo.class
And I get NilClass. Does this mean that foo is an instance of NilClass? And if it is, what does it mean exactly when I call
foo "hello world"
If foo is an object, what method am I calling when I make the statement as above. Also, if it an object, does that mean I can modify it and add another method to it (say bar) where I could possibly make the following statment:
foo.bar(some variables)
Sorry, I'm just a little confused on this point. Any clarification is very much appreciated! Thanks!
User defined global functions (top-level functions) are instance methods of Object (even though the class of self is not Object).
Top-level methods are always private.
As Wikipedia states:
All methods defined outside of the scope of a particular object are actually methods of the Object class.
Ruby is actually "multi-paradigm". It supports object-oriented, functional, imperative (and a few others) paradigms.
Being "fully object-oriented" doesn't mean you only support the object-oriented paradigm. As long as you support all the features that make up object-oriented programming (classes, instances, polymorphism, etc) then you can still support additional paradigms and still be "fully object-oriented".
foo.class first calls the method foo, which returns nil, and then calls the method class on the object returned from foo, namely nil.
In pseudocode notation, evaluating the code step-by-step:
foo.class
==> { print text }.class
==> { nil }.class
==> nil.class
==> NilClass
You can get a method as an object. To use your example:
def foo(text)
print text
end
and then expand upon it:
method_as_object = method(:foo)
method_as_object.call('bar') #=> bar
Typically though, when you define a method, you just define it as a method of the current scope (which is by default the Object class)
To expand on Justice's example, you can take this even further.
def foo
puts "foo"
end
foo.class
==> NilClass
NilClass.class
==> Class
Class.superclass
==> Module
Module.superclass
==> Object
Object.superclass
==> BasicObject
Everything is an instance of class BasicObject at the very least.
< Is Class declaration an eyewash in ruby? Is everything really object oriented? >
Following link best explains how ruby is fully Object oriented so much so that the basic constructs like class Someclass are creating objects from objects.

Does ruby provide a method to show the hierarchy calls?

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]

Resources