5

コード全体に print-statement を入れ始めました。出力が乱雑にならないように、次のようにしました。

dputs LEVEL, "string"

ここLEVELで、エラーの場合は 0、重要な場合は 1、冗長の場合は 5 で、 と比較されDEBUG_LEVELます。今私の問題は、次のようなステートメントです。

dputs 5, "#{big_class.inspect}"

1 に設定した場合も、文字列は常に評価さDEBUG_LEVELれます。この評価には時間がかかる場合があります。私のお気に入りの解決策は次のようなものです。

dputs 5, '#{big_class.inspect}'

必要に応じて文字列を評価します。しかし、評価できる形式で文字列を取得することはできません。したがって、私が思いつくことができる唯一の考えは次のとおりです。

dputs( 5 ){ "#{big_class.inspect}" }

しかし、これは見た目が悪いだけです。では、「#{}」文字列を評価するにはどうすればよいでしょうか?

4

4 に答える 4

6

これは、 (経由で)dputs使用することで実行できます。そうすれば、出力することがわかっている場合を除き、補間された文字列を作成しないことを決定できます。sprintf%

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

または、あなたが示唆するように、ブロックが実際に実行されるまで補間を延期するブロックを渡すことができます。

def dputs(level, &string)
  raise ArgumentError.new('block required') unless block_given?
  puts string.call if level <= LEVEL
end
于 2012-10-20T17:17:53.947 に答える
1

私はあなたがそこに醜いをかわすことができるとは思わない。補間は、dputsが評価するまで延期するブロック内に配置しない限り、dputsの呼び出しの前に行われます。dputsがどこから来ているのかわからないので、そのセマンティクスが何であるかはわかりませんが、ブロックによって必要な遅延評価が得られると思います。きれいではありませんが、それは仕事をします。

于 2012-10-20T17:19:24.003 に答える
0

OK、明らかに私は怠惰すぎました。これを行うにはもっとクリーンな方法が必要だと思いました.Rubyは最高のプログラミング言語であり、すべてです;)次のような文字列を評価するには

a = '#{1+1} some text #{big_class.inspect}'

必要な場合にのみ、文字列を調べて、遭遇したすべての「#{}」を評価するよりも良い方法を見つけられませんでした。

str = ""
"#{b}\#{}".scan( /(.*?)(#\{[^\}]*\})/ ){
  str += $1
  str += eval( $2[2..-2] ).to_s
}

明確にしたくない場合は、一時変数strを取り除くことができます。

"#{b}\#{}".scan( /(.*?)(#\{[^\}]*\})/ ).collect{|c|
  c[0] + eval( c[1][2..-2] ).to_s
}.join

String.scan-method は、すべての '#{}' ブロックを調べます。複数ある可能性があるため、それを評価し ( 2..-2は "#{" と "}" を切り取ります)、それをまとめます。残りの文字列と一緒に。

'#{}' ブロックで終わらない文字列のコーナー ケースでは、念のために空のブロックが追加されます。

しかし、Ruby を数年使用した後でも、これはまだぎこちなく、C っぽい感じがします。おそらく、新しい言語を学ぶ時が来ました!

于 2012-10-22T20:54:29.980 に答える