懒惰评估"#{}" - ruby​​中的字符串

ine*_*iti 4 ruby string eval

我开始在我的代码中放置print语句.为了不弄乱输出,我做了类似的事情:

dputs LEVEL, "string"
Run Code Online (Sandbox Code Playgroud)

其中LEVEL0表示错误,1表示重要... 5表示详细,并与之比较DEBUG_LEVEL.现在我的问题是,在一个声明中,如:

dputs 5, "#{big_class.inspect}"
Run Code Online (Sandbox Code Playgroud)

如果我设置DEBUG_LEVEL为1 ,则始终评估字符串.此评估可能需要很长时间.我最喜欢的解决方案是:

dputs 5, '#{big_class.inspect}'
Run Code Online (Sandbox Code Playgroud)

然后根据需要评估字符串.但我无法以我能评估的形式获得字符串.所以我能想到的唯一想法是:

dputs( 5 ){ "#{big_class.inspect}" }
Run Code Online (Sandbox Code Playgroud)

但这看起来很难看.那么如何评估'#{}'字符串呢?

And*_*all 6

你可以通过dputs使用sprintf(via %)来做到这一点.这样它可以决定不构建插值字符串,除非它知道它将打印它:

def dputs(level, format_str, *vars)
  puts(format_str % vars) if level <= LEVEL
end

LEVEL = 5
name = 'Andrew'
dputs 5, 'hello %s', name
#=> hello Andrew
Run Code Online (Sandbox Code Playgroud)

或者,正如您所建议的那样,您可以传递一个块,该块将推迟插值直到块实际运行:

def dputs(level, &string)
  raise ArgumentError.new('block required') unless block_given?
  puts string.call if level <= LEVEL
end
Run Code Online (Sandbox Code Playgroud)


Mik*_*sen 1

我认为你无法躲避那里的丑陋。插值发生在调用 dputs 之前,除非您将其放入块内,这会推迟插值直到 dputs 对其求值为止。我不知道 dputs 来自哪里,所以我不确定它的语义是什么,但我的猜测是该块会给你带来你想要的惰性评估。不漂亮,但它可以完成工作。