不懂Rubyljust/rjust/center方法

Don't understand Ruby ljust/rjust/center methods

我正在学习嵌套,我的任务是让每一行都以缩进开头。这是我的代码,但它不起作用

$nestingDepth = 0

def logger description, &block
    puts "Beginning #{description}".rjust($nestingDepth)
    puts $nestingDepth
    $nestingDepth = $nestingDepth + 10
    result = block.call
    $nestingDepth = $nestingDepth - 10
    puts $nestingDepth
    puts "End of #{description} block that returned #{result}".rjust($nestingDepth)
end

logger "first block" do 
    logger "second block" do
        logger "third block" do 
            puts "third block part"
        end
        puts "second block part"
    end
    puts "first block part"
end

您的问题是 rjust 需要一个大于应用它的字符串长度的整数。您的字符串是:

"Beginning #{description}" 

变成:

Beginning first block
Beginning second block

在大多数情况下,这是 21 或 22 的长度。最大的 $nestingdepth 是 20。当整数小于字符串的长度时,它只是 returns没有填充的字符串。如果我以 25 的嵌套深度启动脚本,您会看到它展开。

                             Beginning first block
25
                                      Beginning second block
35
                                                 Beginning third block
45

您的代码有几个问题:

  • 您正在使用全局变量,这通常不是一个好主意,请将其作为参数传递下去。为此,您可以使用定义记录器和日志方法的 DSL class。
  • 你在块内调用 puts,但你从未更改它的定义,我不明白你是如何期望它打印缩进字符串的,它只会正常打印字符串而不用缩进。为此,您需要定义一个特殊的方法来打印缩进,例如log
  • 您正在调用 rjust,期望它会缩进字符串。这个方法有不同的目的——用指定的长度向右对齐一个字符串(即左填充)。如果字符串长于指定长度,则返回原始字符串。要真正缩进一个字符串,你应该做 puts ' ' * nestingDepth + string。一开始看起来很神奇,但是 * 运算符只是重复字符串,例如'abc' * 3 #=> 'abcabcabc'

综合起来我会这样做:

class DSL
  def initialize
    @depth = 0
  end

  def logger(description, &block)
    log "Beginning #{description}"
    @depth += 1
    result = instance_eval(&block)
    @depth -= 1
    log "End of #{description} that returned #{result}"
  end

  def log(string)
    puts indent + string
  end

  private

  def indent
    ' ' * (10 * @depth)
  end
end

def logger(*args, &block)
  DSL.new.logger(*args, &block)
end

示例:

logger "first block" do 
  logger "second block" do
    logger "third block" do 
      log "third block part"
    end
    log "second block part"
  end
  log "first block part"
end

这会打印:

Beginning first block
          Beginning second block
                    Beginning third block
                              third block part
                    End of third block that returned
                    second block part
          End of second block that returned
          first block part
End of first block that returned