ruby中容易犯的错误

• First and foremost, run your scripts with warnings enabled (the -w command-line
  option).
• If you happen to forget a “,” in an argument list—especially to print—you can
  produce some very odd error messages.
• A parse error at the last line of the source often indicates a missing end keyword,
  sometimes quite a bit earlier.
• An attribute setter is not being called. Within a class definition, Ruby will parse
  setter= as an assignment to a local variable, not as a method call. Use the form
  self.setter= to indicate the method call.
        class Incorrect
          attr_accessor :one, :two
          def initialize
             one = 1           # incorrect - sets local variable
             self.two = 2
          end
        end
        obj = Incorrect.new
        obj.one    → nil
        obj.two    →2
• Objects that don’t appear to be properly set up may have been victims of an incor-
  rectly spelled initialize method.
        class Incorrect
          attr_reader :answer
          def initialise           # < < < spelling error
             @answer = 42
          end
        end
        ultimate = Incorrect.new
        ultimate.answer       → nil
  The same kind of thing can happen if you misspell the instance variable name.

        class Incorrect
          attr_reader :answer
          def initialize
            @anwser = 42        #<« spelling error
          end
        end
        ultimate = Incorrect.new
        ultimate.answer    → nil
• Block parameters are in the same scope as local variables. If an existing local
  variable with the same name as a block parameter exists when the block executes,
  that variable will be modified by the call to the block. This may or may not be a
  Good Thing.
        c = "carbon"
        i = "iodine"
        elements = [ c, i ]
        elements.each_with_index do |element, i|
          # do some chemistry
        end
        c   → "carbon"
        i   →1
• Watch out for precedence issues, especially when using {} instead of do/end.
        def one(arg)
          if block_given?
            "block given to 'one' returns #{yield}"
          else
            arg
          end
        end
        def two
          if block_given?
            "block given to 'two' returns #{yield}"
          end
        end
        result1 = one two {
          "three"
        }
        result2 = one two do
          "three"
        end
        puts "With braces, result = #{result1}"
        puts "With do/end, result = #{result2}"
  produces:
        With braces, result = block given to 'two' returns three
        With do/end, result = block given to 'one' returns three

• Output written to a terminal may be buffered. This means you may not see a mes-
  sage you write immediately. In addition, if you write messages to both $stdout
  and $stderr, the output may not appear in the order you were expecting. Always
  use nonbuffered I/O (set sync=true) for debug messages.
• If numbers don’t come out right, perhaps they’re strings. Text read from a file will
  be a String and will not be automatically converted to a number by Ruby. A call
  to Integer will work wonders (and will throw an exception if the input isn’t a
  well-formed integer). A common mistake Perl programmers make is
        while line = gets
          num1, num2 = line.split(/,/)
          # ...
        end
  You can rewrite this as
        while line = gets
          num1, num2 = line.split(/,/)
          num1 = Integer(num1)
          num2 = Integer(num2)
          # ...
        end
  Or, you could convert all the strings using map.
        while line = gets
          num1, num2 = line.split(/,/).map {|val| Integer(val) }
          # ...
        end
• Unintended aliasing—if you are using an object as the key of a hash, make sure it
  doesn’t change its hash value (or arrange to call Hash#rehash if it does).
        arr = [1, 2]
        hash = { arr   => "value" }
        hash[arr]       → "value"
        arr[0] = 99
        hash[arr]            nil
                        →
        hash.rehash          {[99, 2]=>"value"}
                        →
        hash[arr]            "value"
                        →
• Make sure the class of the object you are using is what you think it is. If in doubt,
  use puts my_obj.class.
• Make sure your method names start with a lowercase letter and class and constant
  names start with an uppercase letter.
• If method calls aren’t doing what you’d expect, make sure you’ve put parentheses
  around the arguments.

• Make sure the open parenthesis of a method’s parameter list butts up against the
  end of the method name with no intervening spaces.
• Use irb and the debugger.
• Use Object#freeze. If you suspect that some unknown portion of code is setting
  a variable to a bogus value, try freezing the variable. The culprit will then be
  caught during the attempt to modify the variable.


posted on 2007-02-14 14:39  woodfish  阅读(357)  评论(0编辑  收藏  举报

导航