Ad
  • Custom User Avatar

    For the Ruby version:

    1. Don't use clsses as a way to namespace static methods
    2. Use module_function to define module-level methods, not def self.foo. This plays nicer with both include and extend.

    See my soln: http://www.codewars.com/kata/reviews/54f7910c20de9891c400004b/groups/5545e362647c1f924600007b

  • Custom User Avatar

    This kata needs a lot of work. To those struggling with this kata, it's honestly not worth your time. You're better off reading reading the ostruct.rb file that comes with the default Ruby interpreter to learn how this sort of thing should work.

    1. The instructions are unclear
    2. The goal is unclear — are we trying to make a Hash-like object that is indifferent to whether a Symbol or String is used as a key?
    3. The standard library's OpenStruct class appears to do all this and in a more sensible way (see this screenshot)
    4. It's Bad Ruby Style™ to start method names with an underscore (feels like a Python-ism)
    5. It's a Bad Idea™ to override method_missing without calling super.
    6. It's a Bad Idea™ to create objects that respond to a new method foo without having respond_to?(:foo) return true.
    7. It's a Bad Idea™ to re-open built-in classes and add new methods, let alone override standard methods. What if the built-in Hash class already defined its own method_misssing? This is why libraries like hashie subclass Hash.
    8. Even then, there are good arguments for why libraries like hashie are harmful and almost never what you really want.
  • Custom User Avatar

    You might be interested in a solution I posted: http://www.codewars.com/dojo/katas/reviews/52255487906b0c1733000452/groups/522cd249900801524d000063

    It starts by implementing "exact arithmetic" in the field extension ℚ(𝜑) = {a + b𝜑 | a,b ∈ ℚ}, where ℚ are the rational numbers and 𝜑 is the golden ratio. Since

    fib(n) = [𝜑 ⁿ - (1-𝜑) ⁿ]/(2𝜑 - 1)
    

    we can implement the "explicit formula" by implementing an algorithm for exponentiation in ℚ(𝜑) .

    In the code, the representation works as follows

    PhiRational.new(a,b)  # a + b𝜑
    PhiRational.new(0,1) # 𝜑
    # etc.
    
  • Custom User Avatar

    Why? It's not like you have to do every exercise.

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    Just FYI, in Ruby you can do

    some_array.each(&:foo)
    

    instead of

    some_array.each { |item| item.foo }
    

    This holds for any method which takes a block. The ampersand ("&") tells Ruby that this argument should serve as the block argument to the method and Ruby will then call to_proc on that object. In this case, Ruby will call Symbol#to_proc since you're passing in a symbol, which works thus:

    class Symbol
      def to_proc
        Proc.new { |object| object.send(self) }
      end
    end
    
  • Custom User Avatar

    This code isn't just unidiomatic, it's a little bit abusive. :)

    You define a constant CHILDS and then modify it. Don't modify constants! Ruby lets you do this—don't ask me why—but it will at least throw a warning about the constant already being defined.

    Also, the plural of "child" is "children," which would be a better variable name.

  • Custom User Avatar

    The plural of "child" is "children," which would be the more appropriate variable name. Also, there's no reason to call Array#map here. You should just call Array#each.

  • Custom User Avatar

    There's no reason to call Array#map here. You should just call Array#each.

  • Custom User Avatar

    Idiomatically, there are three things off about your code:

    1. If a method takes a Class as input, one traditionally uses the variable name klass.
    2. Don't put spaces before and after method arguments.
    3. If you have a multi-line block, use do...end, not {...}.
  • Custom User Avatar

    There's no reason to call Array#map here. You should just call Array#each.

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    To avoid creating a spurious Range object I might do

    s = Array.new(n+1) { |i| i }
    

    instead of

    s = (0..n).to_a
    

    Also, rather than calling Math.sqrt, it will likely be faster to either convert bound to a Fixnum or do

    break if p*p > n
    

    so that you can avoid unnecessary floating-point arithmetic.

  • Custom User Avatar

    Also, I'll add that for the same reason it's important to point out to a student that snake_case is merely a convention in Ruby. Usually I'd give a student a little lesson that goes something like this...

    You can name methods pretty much anything you want in Ruby, so long as the names begin with a lower-case letter. Other languages have other conventions. For example, JavaScript uses camelCase everywhere.

    Using camelCase in Ruby is like speaking French with a terrible accent. You're understood, but you're also marked as an absolute foreigner and it make it difficult to communicate effectively. When you're a beginner is the time to learn the conventions and make them a habit. It will be harder if you learn some idiosyncratic set of conventions now and have to un-learn them later.

    For example, if you ever want to contribute to an open source project, they'll insist on you following not just the conventions of the language, but also the conventions of the project. Your pull requests will simply be rejected.

  • Custom User Avatar

    Well, I've been assuming that a big part of this site is helping folks get better at the various languages. Beginners at anything are a bit like children: they absorb a million details, said and unsaid, and translate them into often-incorrect rules,. For example, when a child gets corrected for saying "I brang the water to Mom" and is exasperated when corrected, arguing "But if we say ring/rang why don't we say bring/brang?!"

    You can call that pedantry if you want, but what you're doing by violating the naming conventions of a language is teaching beginners another set of conventions, whether you like it or not. I personally think that's a disservice to students.

    To give you an example of how subtle this effect is, here is something I actually witnessed while teaching someone the basics of programming. We're covering variables and variable assignment in Ruby and they see

    my_name = "Jesse"
    my_age = 29
    my_city = "San Francisco, CA"
    
    puts "Hello!  My name is #{my_name}.  I'm #{my_age} years old and live in #{my_city}."
    

    Later, I see code like this:

    my_counter = 0
    while my_counter < array.length
      puts array[my_counter]
    end
    

    I see the code and remark, "Normally we give counter variables simple names like i, j, etc." They reply, "Oh, I thought the name of every variable had to start with my_! You mean it can be anything?"

    That's how beginners work, so every aspect of your code is going to be absorbed in that way.

  • Loading more items...