In Ruby- Could anyone help me to understand how meta class differs from real class ? Examples with discussion could be better to understand the core of the concept
on 2013-02-20 22:54
on 2013-02-20 23:20
I think I best understood this problem when trying to write my own programming languages. Here's the basic case that you actually end up using (albeit indirectly) almost all of the time in Ruby. Everything in ruby is an object, objects respond to methods. This means that an object must know about the methods it responds to. So lets take a class for an example class MyClass def my_instance_method; end def self.my_class_method; end end So in the c land we have some class which needs to hold both of these methods, but here's what is interesting, objects only hold their instance methods. This means in c land the MyClass object only knows about it's my_instance_method. Well than, what knows about the class method? We can't put it's my_class_method on it's superclass because that would add my_class_method to Class. This presents a problem. We solve this by adding a class in between MyClass and Class. This goes by many names, eigenclass, metaclass, or in the actual ruby implementation the singleton_class. Here's an example showing how this method is attached: 水~/Code/ruby/with_c‹1.9.3-p374›$ irb irb(main):001:0> class MyClass irb(main):002:1> def my_instance_method irb(main):003:2> end irb(main):004:1> def self.my_class_method irb(main):005:2> end irb(main):006:1> end => nil irb(main):007:0> MyClass.singleton_class => #<Class:MyClass> irb(main):008:0> MyClass => MyClass irb(main):009:0> MyClass.new.method(:my_instance_method).owner => MyClass irb(main):010:0> MyClass.method(:my_class_method).owner => #<Class:MyClass> In the above example you can see the my_class_method is attached to the singleton_class. To be honest this is a pretty elegant solution to this problem.
on 2013-02-20 23:27
This looks pretty comprehensive. http://ruby-metaprogramming.rubylearning.com/html/... After a quick scan I'd say that in Ruby every Metaclass is a Class, and every Class has the capability to be turned into a Metaclass since Ruby can modify classes even at runtime. Metaclasses can even build themselves, but anyways I think you should read the above link if you haven't already. "Why the lucky stiff" has a good way of explaining concepts in a concrete fashion :)
on 2013-02-20 23:30
Matt Mongeau wrote in post #1098088: > > class MyClass > def my_instance_method; end > def self.my_class_method; end > end Is "my_class_method" is a class method?
on 2013-02-20 23:31
Matt Mongeau wrote in post #1098088: > adding a class in > between MyClass and Class. I didn't know this is how it worked. Very succinct.
on 2013-02-20 23:38
Xavier R. wrote in post #1098096: > Matt Mongeau wrote in post #1098088: > >> >> class MyClass >> def my_instance_method; end >> def self.my_class_method; end >> end > > Is "my_class_method" is a class method? My point was that technically there is no such thing as class methods. Class methods are simply instance methods on the singleton_class.
on 2013-02-21 05:17
On Wed, Feb 20, 2013 at 3:54 PM, Xavier R. <lists@ruby-forum.com> wrote: > > As far as I know, there are only two differences: 1. It can't be instantiated Object.new.singleton_class.new # ~> -:1:in `new': can't create instance of singleton class (TypeError) # ~> from -:1:in `<main>' 2. It does not show up in the ancestry Superclass = Class.new # Define a method that will be in the ancestry of the subclass Superclass.define_singleton_method(:abc) { 123 } # We inherit the abc method from the singleton class of Superclass Subclass = Class.new Superclass Subclass.abc # => 123 Subclass.method(:abc).owner # => #<Class:Superclass> Superclass.singleton_class # => #<Class:Superclass> # But it does not show up in the ancestry Subclass.ancestors # => [Subclass, Superclass, Object, Kernel, BasicObject] Subclass.singleton_class.ancestors # => [Class, Module, Object, Kernel, BasicObject]
on 2013-02-21 05:28
Josh Cheek wrote in post #1098131:
> 2. It does not show up in the ancestry
Right ruby will specifically skip over this class when looking at the
class of an object and in the ancestry, but you can see it with a little
C hackery.
水~/Code/ruby/with_c‹1.9.3-p374›$ cat inheritance.c
#include "ruby.h"
VALUE real_klass(VALUE self) {
return RBASIC(self)->klass;
}
void Init_inheritance() {
rb_define_method(rb_cObject, "real_class", real_klass, 0);
}
水~/Code/ruby/with_c‹1.9.3-p374›$ cat test.rb
require_relative 'inheritance'
class Foo
end
puts "Class: #{Foo.class}"
puts "Real class: #{Foo.real_class}"
水~/Code/ruby/with_c‹1.9.3-p374›$ ruby test.rb
Class: Class
Real class: #<Class:Foo>
on 2013-02-21 21:47
Xavier R. wrote in post #1098080: > In Ruby- > > Could anyone help me to understand how meta class differs from real > class ? > > Examples with discussion could be better to understand the core of the > concept Not sure what you mean by "real class". Everything in Ruby is an object. All objects inherit from BasicObject. Classes in ruby are instances of the Class object, meaning: MyClass = Class.new Instance methods are on an instance of a class. Class methods, singleton methods of the eigenclass (metaclass), are called on the class constant. A good example is the Math module (Class is a subclass of Module). The Math module provides a bunch of utility methods, that wouldn't be as useful if they had to be called on instances of an object. you can easily do x = Math.sqrt(144) otherwise you'd have to open up the Fixnum class and add a sqrt method, in order to x = 144.sqrt but that would only be on Fixnum. What if the number was a Float 144.0, or a Bignum ? Another example, Let's say we have a class Student. stu = Student.new #(btw 'new' is a singleton method) some logical instance methods might be calculate_GPA, show_schedule etc. stu.calculate_GPA But what if we wanted to know the total average GPA of all our students? Calling stu.average_GPA does not make sense, because we're calling it on a specific student. It makes the code confusing. Instead we should have that method on the Eigenclass def Student.average_GPA; ..calculate GPA from all student records; end so then Student.average_GPA() would give us the average GPA amongst all our students, and it is namespaced in a way that is logical.
on 2013-02-21 23:55
On Wed, Feb 20, 2013 at 3:54 PM, Xavier R. <lists@ruby-forum.com> wrote: > In Ruby- > > Could anyone help me to understand how meta class differs from real > class ? > > Examples with discussion could be better to understand the core of the > concept > Core concept for meta class is that every class has it's own class. One view would be that it's an anonymous class or hidden class as I've seen explained. Instead of producing and example for you as they can provide a handful of use cases and design concepts for your program's model it may be better for you to view various takes on the interwebz for it's general concept though various combinations of code and style. More importantly it may be useful to understand that a meta class is just as real as a class though it's scoping does not follow the normal method lookup chain at the top level instance. One may also consider further modification after the instance is constructed by redefinition of the instance object. Take the time and experiment with both opening up the meta class in your class templates. Create your own macros( for example try to make your own attribute generators). explore post instantiations with singleton assignment and delegations. More importantly explore these concepts within the repl and editor combination. Think of the concept that Matz created ruby to be a "Programmable Programming Language". Though that quote was from another language which heavily influenced ruby it's a major part of ruby's computational model. Also instead of getting stuck on the recursive writing style of various tutorials which attempt to verbalize the Class<=>Object relationship and paradigm consider simply taking the time and coding simple functions yourself while viewing the yielded results from trial and error will provide you more substantial experience on grokking the interpreter (as well as how the interpretation of the code works) which will get you closer to understanding the sheer power and control available to you with this overly malleable and versatile programming language. If you are really stuck work though this one: http://madebydna.com/all/code/2011/06/24/eigenclas... Though the link to _why's metaclass earlier in this thread should also be explored as well as many of the other blog posts which disseminate the subject exhaustively. Metaprogramming in Ruby: Its All About the Self was another one which provides trivial examples. For real world examples you'll want to explore how domain specific micro-languages in ruby are implemented which will provide the end result of combining the automata, stream processing, and list reference and recursion techniques within the context of the programming language. ~Stu
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.