Ruby 这是不是太复杂而无法接受?

Ruby 这是不是太复杂而无法接受?,ruby,refactoring,Ruby,Refactoring,我正在写一个Befunge翻译。我很好奇这种方法的风格有多糟糕 def adv(r, c, dir, torus) case dir when 0; r == 0 ? (return torus.n_o_l - 1, c) : (return r - 1, c) when 1; c == torus.r_l - 1 ? (return r, 0) : (return r, c + 1) when 2; r == torus.n_o_l - 1 ? (return 0, c) :

我正在写一个Befunge翻译。我很好奇这种方法的风格有多糟糕

def adv(r, c, dir, torus)
  case dir
  when 0; r == 0 ? (return torus.n_o_l - 1, c) : (return r - 1, c)
  when 1; c == torus.r_l - 1 ? (return r, 0) : (return r, c + 1)
  when 2; r == torus.n_o_l - 1 ? (return 0, c) : (return r + 1, c)
  when 3; c == 0 ? (return r, torus.r_l - 1) : (return r, c - 1)
  end
end
如果我只需要使用更标准的if/else构造,我知道如何重新格式化它,但我很好奇这在源代码中会有多么糟糕。

我的尝试:

def adv(r, c, dir, torus)
  case dir
  when 0; r == 0 ? [torus.n_o_l - 1, c] : [r - 1, c]
  when 1; c == torus.r_l - 1 ? [r, 0] : [r, c + 1]
  when 2; r == torus.n_o_l - 1 ? [0, c] : [r + 1, c]
  when 3; c == 0 ? [r, torus.r_l - 1] : [r, c - 1]
  end
end

省略
return
,因为
case
在默认情况下总是返回某些内容。

您是在征求意见,所以您的问题可能不会太长,但我的建议是:

def adv(r, c, dir, torus)
  case dir
  when 0
    case r
    when 0 then             [torus.n_o_l-1, c]
    else                    [r-1, c]  
    end
  when 1
    case c     
    when torus.r_l-1 then   [r, 0]
    else                    [r, c+1]
  when 2
    case r
    when torus.n_o_l-1 then [0, c]
    else                    [r+1, c]
  when 3
    case c
    when 0 then             [r, torus.r_l-1]
    else                    [r, c-1]
  end
end

有时候,一个人想要做的事情是无法简化的。我想这里就是这样。如果你不能把它分解成碎片,你至少可以想想我们人类是如何处理我们阅读的信息的。我发现您的代码很难理解,因为返回值在视觉上与条件语句混合在一起。我通过将所有返回值放在一列中来解决这个问题。对于case语句中
dir
的每个值,如果。。。其他的结束或
或第二个case语句。我之所以选择最后一个,是因为我认为它最容易阅读,并且导致的“代码混乱”最少。

您的代码太糟糕了。我会这样做:

def adv(r, c, dir, torus)
  case dir
  when 0
    r = torus.n_o_l if r.zero?
    [r - 1, c]
  when 1
    c = -1 if c == torus.r_l - 1
    [r, c + 1]
  when 2
    r = -1 if r == torus.n_o_l - 1
    [r + 1, c]
  when 3
    c = torus.r_l if c.zero?
    [r, c - 1]
  end
end

就我个人而言,我至少会将每个操作剥离成自己的方法。暂时忽略简洁性参数,我的主要原因是可以独立于case语句测试每个操作

def adv(r, c, dir, torus)
  case dir
  when 0; op1(r, c, torus)
  when 1; op2(r, c, torus)
  when 2; op3(r, c, torus)
  when 3; op4(r, c, torus)
  end
end

def op0(r, c, torus)
  r == 0 ? [torus.n_o_l - 1, c] : [r - 1, c]
end

def op1(r, c, torus)
  c == torus.r_l - 1 ? [r, 0] : [r, c + 1]
end

def op2(r, c, torus)
  r == torus.n_o_l - 1 ? [0, c] : [r + 1, c]
end

def op3(r, c, torus)
  c == 0 ? [r, torus.r_l - 1] : [r, c - 1]
end
至于“我个人喜欢我的代码尽可能短”,你显然还没有学会应该这么做


别担心-你会学到的。

我建议对变量使用更好的名称-什么是
r
,什么是
c

我最近写了一篇文章,其中我添加了一个人类友好的方向常数。看起来像是

给定该常数,计算指令的下一个位置(下面称为
code\u指针
)非常简单:

# Moves the `code_pointer` in the specified `code_direction`, and returns the modified
# `code_pointer`
#
# @param code_pointer [Hash] the current +code_pointer+, in the form: `{x: 0, y: 3}`
# @param code_direction [Hash] the current +code_direction+, in the form: `{x: 0, y: 1}`
# @return [Hash] the modified `code_pointer`
def move_pointer(code_pointer, code_direction)
  code_pointer[:x] += code_direction[:x]
  code_pointer[:y] += code_direction[:y]

  code_pointer
end

这并不可怕,但你也不会因为可读性而获得任何奖励。建议不要使用“?”和重写作为返回废话,如果;return blah 2这段代码在做什么?@asiniy'adv'是“advance”的缩写,它在Befunge'93中移动理论指针。这并不像在一个方向上移动那么简单,因为在Befunge'93中你应该有一个环形阵列。它或多或少只是确保没有越界错误。
我个人喜欢我的代码尽可能短,可读性或不可读。
不要。@Mast,你能详细说明一下吗?我倾向于同意你,但主要是出于自私的原因。然而,我并不认为读者需要花一点时间来理解简洁的(好的)代码是件坏事,因为这样做有教育价值
将案例条件与特定代码分开。hfenan希望代码尽可能短=)我不知道why@asiniy这并不是一个很好的理由,我只是喜欢很短的代码。非常好,主要是因为您在返回值中暴露(可能很重要)模式的方式(我错过了)。我建议“可怕”而不是“可怕”。非常干净的解决方案。。1+“你的代码太糟糕了。”你的评论直截了当。不过说实话。我喜欢你的方法,因为它很好(哦……)我讨厌这个!讨厌它!讨厌它!我讨厌它!这是来自学校的,真正微小的方法越多越好。这让我发疯。等等,我已经疯了。你的地址是什么,瑞吉?我想顺道过来打个招呼。
# Moves the `code_pointer` in the specified `code_direction`, and returns the modified
# `code_pointer`
#
# @param code_pointer [Hash] the current +code_pointer+, in the form: `{x: 0, y: 3}`
# @param code_direction [Hash] the current +code_direction+, in the form: `{x: 0, y: 1}`
# @return [Hash] the modified `code_pointer`
def move_pointer(code_pointer, code_direction)
  code_pointer[:x] += code_direction[:x]
  code_pointer[:y] += code_direction[:y]

  code_pointer
end