任何人都可以向我解释这个Ruby方法吗?

时间:2014-08-22 12:26:25

标签: ruby

任何人都可以向我解释这种方法吗?如果我发送index as 4, code实际返回的内容是什么?。

def getOffset(index)
    @baseIndex = 0 if @baseIndex.nil?
    raise IndexError if not \
           (@baseIndex ... @baseIndex + length) === index
    return index - @baseIndex
end

我无法理解第一行之后的部分。

4 个答案:

答案 0 :(得分:5)

清理代码

你的方法的第二行看起来很混乱,让我们重构它:

raise IndexError if not \
       (@baseIndex ... @baseIndex + length) === index

以上实际上是一行:

raise IndexError if not (@baseIndex ... @baseIndex + length) === index

不应显式调用大小写等于运算符Range#===。请改用include?,它也是如此:

raise IndexError if not (@baseIndex ... @baseIndex + length).include?(index)

最后,if not可以写成unless,并且可以删除一些空格:

raise IndexError unless (@baseIndex...@baseIndex + length).include?(index)

更好。

它做了什么?

我们假设@baseIndex = 4length = 10

raise IndexError unless (@baseIndex...@baseIndex + length).include?(index)
# is evaluated as:
raise IndexError unless (4...4 + 10).include?(index)
# is evaluated as:
raise IndexError unless (4...14).include?(index)

除非IndexError介于index4之间(不包括14),否则会引发14。否则,它继续下一行并返回index - @baseIndex

还有什么?

  • 使用snake_case获取方法名称和变量(@base_index
  • 除非必要,否则不要写return
  • 避免使用getset前缀,即def offset通常就够了
  • @base_index中初始化initializer(不在offset方法中):

    def initialize
      @base_index = 0
    end
    
  • 提取范围计算:

    def valid_range
      @base_index...@base_index + length
    end
    
    def offset(index)
      raise IndexError unless valid_range.include?(index)
      index - @base_index
    end
    

答案 1 :(得分:1)

# this sets the base index to 0 unless `@baseIndex` is defined
@baseIndex = 0 if @baseIndex.nil? 

# this raises an error if the index you passed in is larger than the size of your array
raise IndexError if not (@baseIndex ... @baseIndex + length) === index 

# this returns the offset
return index - @baseIndex

因此,如果您未设置@baseIndex并通过4,则此方法将返回4
如果您将@baseIndex设置为2,则此方法将返回2 如果您将@baseIndex设置为5,则此方法将返回IndexError

答案 2 :(得分:1)

===用于测试when语句的case子句内的相等性。

例如:

(1...10) === 5 returns true.
(1...10) === 11 returns false.

答案 3 :(得分:1)

您还可以为了可读性而重构代码,例如

def get_offset_refactor(index)
  @base_index ||= 0
  (@base_index...@base_index + length).include?(index) ? index - @base_index : raise IndexError 
end

这读为

#if base index is not nil use it's value otherwise use 0
@base_index = @base_index || 0
#create a range from @base_index up to be not including @base_index + length
#check if index is included in that range
#if so then return index - @base_index
#otherwise raise an IndexError
(@base_index ... @base_index + length).include?(index) ? index - @base_index : raise IndexError

示例

#because this is not defined anywhere
def length
  5
end
get_offset_refactor(4)

@base_index = @base_index || 0 #@base_index will now = 0 because it was not set 
#next line becomes
(0...(0+5)).include?(4) ? 4 - 0 : raise(IndexError) 
#^[0,1,2,3,4]        ^does this include 4 => yes
#return 4 - 0
#=> 4

如果您使用5运行它会引发它,因为[1,2,3,4]不包含5

希望这有助于您理解此方法高度依赖于一个实例变量@base_index和一个方法/局部变量length