Hey all,
There's a core Class class and core Object class in Ruby library:
First, let's resolve the simple distinction between an Object and Class as envisioned by Smalltalk but within the Ruby context:
#A class is a template used to define methods and properties class Hello attr_accessor :say_what
private def say_what(txt) puts txt + 'my friend' end end
#Objects are the things actually created out of a class and can be used in client code @obj = Hello.new @obj.say_what "hello"
@obj2 = Hello.new @obj2.say_what "bye"
Both @obj and @obj2 instance variables that store an object in a memory location, but both of the objects are part of the blueprint Hello class.
That above is the simple distinction. But you must realize that there is both a class Class and a class Object that can be extended. Let's extend Class and Object:
class Class def dual_accessor(*attributes) end end
class Object def try_safe(method_chain) self.send_method_chain(method_chain) end end
When I first look at the above, my understanding is since a class can have a class (static) method, you can specify them as being independent of the object instances of the class: def self.hey end. Hence, those methods will always refer directly to the class itself and return a value for the class. Now when you add methods to class Class, those methods become available to any class that is created as well (since all classes created using class construct inherit from Class) and you can use those methods within any class:
ruby-1.8.7-p330 :020 > class Class ruby-1.8.7-p330 :021?> def huh ruby-1.8.7-p330 :022?> puts 'hey' ruby-1.8.7-p330 :023?> end ruby-1.8.7-p330 :024?> end => nil ruby-1.8.7-p330 :025 > class Pizza ruby-1.8.7-p330 :026?> huh ruby-1.8.7-p330 :027?> end hey => nil
But when we try to call a class (static) method on an instance (an object), since an instance is not a class, but an object that was created, calling a class method (a method defined within class Class or a method defined in class with self) on an instance, raises an exception:
ruby-1.8.7-p330 :054 > class Peach ruby-1.8.7-p330 :055?> def yummy ruby-1.8.7-p330 :056?> puts 'yum yum' ruby-1.8.7-p330 :057?> end ruby-1.8.7-p330 :058?> end => nil ruby-1.8.7-p330 :059 > class Class ruby-1.8.7-p330 :060?> def tasty ruby-1.8.7-p330 :061?> puts 'tasty tasty' ruby-1.8.7-p330 :062?> end ruby-1.8.7-p330 :063?> end => nil ruby-1.8.7-p330 :064 > @yum = Peach.new => #<Peach:0x105e4c2e8> ruby-1.8.7-p330 :065 > @yum.tasty NoMethodError: undefined method `tasty' for #<Peach:0x105e4c2e8> from (irb):65
Now when you extend the Object core library with methods, since the class Class is an object, any class created will inherit the method extended to Object class. Also, since when we create an instance of a class, that instance is an object, that instance will inherit the method extended to Object class:
ruby-1.8.7-p330 :041 > class Apple ruby-1.8.7-p330 :042?> def like_apples? ruby-1.8.7-p330 :043?> puts 'true' ruby-1.8.7-p330 :044?> end ruby-1.8.7-p330 :045?> end => nil ruby-1.8.7-p330 :046 > class Object ruby-1.8.7-p330 :047?> def like_apples! ruby-1.8.7-p330 :048?> puts 'hell yeah' ruby-1.8.7-p330 :049?> end ruby-1.8.7-p330 :050?> end => nil ruby-1.8.7-p330 :051 > @apple = Apple.new => #<Apple:0x105f15af8> ruby-1.8.7-p330 :052 > Apple.like_apples! hell yeah => nil ruby-1.8.7-p330 :053 > @apple.like_apples! hell yeah => nil
If a class is an object and an object is a class:
ruby-1.8.7-p330 :039 > Class.kind_of? Object => true ruby-1.8.7-p330 :040 > Object.kind_of? Class => true
Then why can we access an instance method (extended via Object) directly as a class method (as shown above), but we cannot access a class method with an instance of a class (as shown above)?
Thanks for response