

Ruby Koans. Best way to learn Ruby. - milesf
http://rubykoans.com/

======
mapleoin
I just finished this. It took me about 5 hours in all. A good way to spend a
Sunday afternoon I suppose.

I have a good knowledge of Python and have worked with Ruby in the past on a
little Rails project of my own. I had forgotten anything I knew though.
Yesterday, I don't think I would've been able to write a foobaz in ruby
without looking for help online. This proved to be a welcome refresher. It's
also a great way to compare and contrast Python and Ruby. I really like
Python's philosophy and maybe solving all these ruby koans has made me
appreciate Python's simplicity and predictability a bit more.

I wouldn't recommend this to a beginner however. While I think I now have a
pretty good idea of what the language can do, there were no whys or
recommendations about all these features. Maybe it would be a good starting
point for someone coming from a similar language (like Python), before moving
on to a good Ruby book.

------
ericlavigne
There are also functional koans. Same idea for some other languages.

<http://github.com/relevance/functional-koans>

Each of the following languages has its own branch: Clojure, FSharp, Haskell,
and Scala.

------
bradly
Going through these would be useful for any Rubyist, not just those learning.
I have been using Ruby for a while now and I didn't know there was a
difference between string << 'foo' and string += 'foo' until now.

~~~
Groxx
I learned that difference while doing some genetic programming. The difference
is quite visible when you do it a few million times.

------
ximeng

      def test_changing_hashes
        hash = { :one => "uno", :two => "dos" }
        hash[:one] = "eins"
    
        expected = { :one => "eins", :two => "dos" }
        assert_equal expected, hash
    
        # Bonus Question: Why was "expected" broken out into a variable
        # rather than used as a literal?
      end
    

Can anyone help with the bonus question? From searching Google, I read that
the reason:

    
    
        assert_equal { :one => "eins", :two => "dos" }, hash
    

gives an error is that Ruby believes this to be a block. But then why doesn't
it consider the hash to be a block below:

    
    
        expected = { :one => "eins", :two => "dos" }
    

?

Edit: thanks jashkenas for the explanation! Edit2: for anybody else trying
these, I think the version in github is more up-to-date, with some
corrections:

<http://github.com/edgecase/ruby_koans>

~~~
jashkenas
This is one of those gotchas with Ruby's syntax for blocks clashing with
Ruby's syntax for hash literals. I'm not familiar with the details of
precisely why Ruby's parser handles some cases, and not others, but I bet
there's a special case for assignment -- you can't ever assign a block
literal, so it has to be a hash...

Here are some of the variants:

    
    
        method({ ... })  # hash
    
        method { ... }   # block, even though a hash would be possible.
    
        method = { ... } # hash
    
        method a, b, :c => d  # implicit hash
    
        method a, b { ... } # SyntaxError
    
        method(a, b) { ... } # block
    
    

Only #2 in that list is really a problem, because there are situations where
you'd legitimately like to use both.

~~~
andrewvc
This is one reason why I always use parens on my method calls. Some rubyists
find it cluttering, yeah, but I think it makes reading code easier.

The other one to watch out for is precedence of {} vs do; end. Example:

    
    
      > x = [1,2].map do |i| i*2; end
       => [2, 4] 
      > puts [1,2].map do |i| i*2; end
      1
      2
       => nil
      > puts [1,2].map { |i| i*2}
      2
      4
       => nil

~~~
jashkenas
Agreed. It's why we've tried to be careful with lambda/hash/call syntax in
CoffeeScript, especially where some of it is optional, and can be left out.
For example:

    
    
        x = [1, 2].map (i) -> i * 2
    

... is without optional parens.

    
    
        x = [1, 2].map((i) -> i * 2)
    

... is with them.

    
    
        configure start: 10, end: 25
    

... is the syntax for calling a method and passing an implicit hash -- and
with the optional braces and parens added, it's closer to JavaScript...

    
    
        configure({start: 10, end: 25})

------
wriq
There is also a python port available @
<http://wiki.github.com/gregmalcolm/python_koans/>

------
br41n
Already posted <http://news.ycombinator.com/item?id=1622245>

------
xiaoma
Periods. Not a cure for sentence fragments.

------
ScotterC
I used Koans when I first started out. Loved it. Still use it occasionally for
reference.

------
Schmidt
Love it, just what my mind needed to learn better :)

------
giantfuzzypanda
Pretentious

~~~
ximeng
Possibly, although I guess it's trying to play off Ruby's Japanese
connotations and the actual examples inside (slicing arrays containing peanut
butter and jelly) are not particularly pretentious.

Edit: thanks zem: <http://en.wikipedia.org/wiki/Hacker_koan> Edit2: and thanks
angrycoder, I didn't spot that, although the point still stands that peanut
butter is not overly pretentious

~~~
angrycoder
I think you are trying too hard. The most obvious influence is "The Little
Schemer", right down to the peanut butter and jelly references. It is even
listed as an inspiration on website.

