What do I need to know to contribute to Rails?

advertisements

I am a user of Ruby on Rails framework and am thinking of giving back to it by contributing to the code. I understand that there is a need for thorough understanding of the Ruby language concept to contribute? Ive cloned the project, looked at the code, check out the tickets and have no clue how to begin? From what i see the Rails Framework utilizes metaprogramming alot? So what other aspect of Ruby do i have to master in order to start contributing? or to contribute is to know the ins and outs of Ruby? Thank you.!


It has been quite awhile since I ran across ruby code I didn't understand, but there are parts of rails that really push my understanding of ruby.

That being said, even if you are at more of an intermediate level with the language, figuring out how rails works would probably be a great way to up your game.

As for where to begin, I would start by writing plugins. Think of a cool plugin you could write that hasn't been done yet, or something that you think you could do better. Whatever it is you want to do, chances are you are going to need to hook into some sort of rails internals to do it, which will give you a good place to start. Once you have a bit of knowledge of a given area of the framework, see if there are any open bugs in that area you can fix.

The barrier is quite high, since rails is a quite large and complex program written by people who have a high level of mastery with an incredibly flexible language. It is also a great challenge that will probably make you a better programmer in the end. :)

Edit: to help out banister

This is actually pretty interesting if it is a snippet designed to illustrate how class variables and singleton classes work, but there are much clearer ways to accomplish the same thing if it is "real" code.

Singleton Class

In ruby, every object has a parent class that it gets its methods from. This is pretty normal for OO languages. What isn't normal is ruby also has a concept called "object individuation, that means that objects can have methods that are only on a specific instance, but not on the parent class. here is a quick irb example

irb(main):001:0> foo = "bar"
=> "bar"
irb(main):002:0> def foo.foo_method
irb(main):003:1>   "this is _only_ on the foo instance, not on all strings"
irb(main):004:1> end
=> nil
irb(main):005:0> foo.foo_method
=> "this is _only_ on the foo instance, not on all strings"
irb(main):006:0> "bar".foo_method
NoMethodError: undefined method `foo_method' for "bar":String
    from (irb):6
irb(main):007:0> foo = "New string"
=> "New string"
irb(main):008:0> foo.foo_method
NoMethodError: undefined method `foo_method' for "New string":String
    from (irb):8

First, we assign a string to a variable. Next, we define a method on that instance. Calling the method works, but calling it on a new string does not work. Assigning a new string instance to our foo variable also does not have that foo method.

To make object individuation possible, there needs to be something in between the instance, and the parent class. That thing is the singleton class, and every instance has one that is unique from all other object instances. When ruby is looking up a method, it will look at the singleton class before the parent class.

Believe it or not, even if you have never heard of this before, you have probably already used it. If you want to add a "class method" to something, you usually do this

class Foo
  def self.bar
    "i am on the class"
  end
end

Foo.bar #=> "I am on the class"

To start from the top, the statement class Foo is the exact equivalent of this Foo = Class.new do. What is happening is you are assigning a new instance of type Class to the constant Foo. (as an aside, this is what I love about ruby. most of the syntax is actually just sugar around some core concept)

Inside a class definition, self refers to the class, so saying def self.bar is essentially saying "define the method bar on the singleton class of the Class instance that is stored in the constant Foo".

If you find this stuff complex, it is because it is. I don't think there is anything more complected in ruby other then what happens during method lookups, and singleton classes are a big part of what makes it so complex.

Class Variables

A class variable is prefixed by @@, and basically is a variable whose scope is all instances, the class object, and all classes that inherit from the class. I'll do a quick irb to illustrate this in action

irb(main):003:0* class Foo
irb(main):004:1>   @@instance_count = 0
irb(main):005:1>
irb(main):006:1*   def initialize
irb(main):007:2>     @@instance_count += 1
irb(main):008:2>   end
irb(main):009:1>
irb(main):010:1*   def count
irb(main):011:2>     @@instance_count
irb(main):012:2>   end
irb(main):013:1> end
=> nil
irb(main):014:0>
irb(main):015:0* class Bar < Foo
irb(main):016:1> end
=> nil
irb(main):017:0>
irb(main):018:0* f = Foo.new
=> #<Foo:0x7fa9089c7da0>
irb(main):019:0> f.count
=> 1
irb(main):020:0>
irb(main):021:0* b = Bar.new
=> #<Bar:0x7fa9089be0e8>
irb(main):022:0> b.count
=> 2
irb(main):023:0>
irb(main):024:0* f.count
=> 2

First, we define Foo. Foo has a class variable that tracks how many instances were created. To do that, we increment that variable in the constructor, and lastly just define a quick getter. Bar just extends Foo.

Now, to see it in action, we make a new foo, and check the count, which is 1. Next, we create a new bar, and check the count, we are now at 2. Just to make sure that both Foo and Bar share the same count, we check our foo instance again, and it is 2 now.

Class variables are a very situational feature that you usually don't see outside of framework code. It is usually used when you want to keep track of all instances of a given class.

Banisters Code

class << Object.new
  @@var = 6
end 

String.class_variable_get(:@@var) #=> 6

Your code is showing those two concepts in action. First, we open up the singleton class of a new object, and put a class variable on it. If it were anything other then a class variable, those first three lines would be the most useless ruby code in the world. But since it is a class variable, that becomes visible to the class, all instances of the class, all classes that inherit from the class, and all instances of all classes that inherit from the class. Since the class we are talking about is object, that means everything. So doing class_variable_get on String gives it to you, but you could access that variable from any class or instance you wanted to.

I am sorry

This is horribly complected stuff that is very hard to explain clearly. These concepts took me about a week or so of fairly concerted effort to wrap my head around. If you have any questions about what I wrote, feel free to ask, but don't be discouraged if you don't "get it".