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.!
To work on any framework you need to have a reasonable understanding of the language or if you know lots in one certain area but really get in touch with the people and just talk to them ask what there currently working on and if you feel you can help say and give them your ideas, etc.... i mean the dev community is very nice and the fact that they spend there time working on something to give to other people for free so there always happy to help and try and include and let you know if and how you can help.
But mainly, a little more then the ins and outs and best if you know lots in a certain area
The thought is really appreciated. I think you answer the question yourself. If you can't read and/or understand Rails code, then that is the bottle-neck. Without even looking at the code, I'll take a wild guess they use inheritance, mixins and meta-programming. You should definitely try to study those aspects regardless if you will contribute to Rails. They are essential concepts in Ruby, Rails and Ruby/Rails libraries.
RoR has a bunch of places you can start out but they may not be what you're looking at. The first place to start is probably documentation here. You'll need to know a ton of Ruby at a deeply personal level in order to contribute serious core patches, but you can get in on the discussions right now and you can improve documentation in a way that the core team really, really, really needs.
Sorry, better link here
I think you answered a lot of your own questions: yes, you need to understand Ruby to contribute to a Ruby project.
If you want to learn, you can pick up a ticket and start hacking on it: there's nothing quite like jumping in the deep end! However, I think you can only begin to contribute effectively to a project once you've used it enough for yourself to understand:
- What features exist and are useful, and how they work
- What features are lacking and need help
- What's unclear or confusing and needs documentation
All of the above should come from real-world needs: otherwise you can't state your case for why some feature that you thought up needs to be added...
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".
In addition to the comment I left on your original question...
Ryan Bates (of Railscasts) fame recently released 2 screencasts where he walks through the internals of the Rails 3 router. I found it to be a great & eye opening approach to reading and understanding framework code. If you get the opportunity, check them out:
- http://railscasts.com/episodes/231-routing-walkthrough
- http://railscasts.com/episodes/232-routing-walkthrough-part-2
Perhaps these 'casts may help you to be more comfortable in building your approach to getting down with the framework code.
Hope this helps!