不懂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
我正在学习嵌套,我的任务是让每一行都以缩进开头。这是我的代码,但它不起作用
$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