0

再帰的なインデントを行うコード行を書きたいと思っています。グローバルタブ変数を使用してそれを行う方法を調査しています。そこで、次のコードを使用しました。

@@tab = '  '
@@tab_add = '  '
@@nl = "\n"

def helper
    left = @@tab 
    right = @@tab
    @@tab = @@tab + @@tab_add
    str = '<hello>' + @@nl + left + helper2 + right + @@nl + '</hello>'
end 

def helper2
    left = @@tab 
    right = @@tab
    @@tab = @@tab + @@tab_add
    str = '<goodbye>' + @@nl + left + helper3 + right + @@nl + '</goodbye>' 
end 

def helper3
    str =  'dawg'
end

私はそれを行う最もエレガントな方法ではないことを知っていますが、私はただ実験しています. とにかく、私がタイプするとき

helper

私は得る

<hello>
   <goodbye>
     dawg
</goodbye>
</hello>

しかし、さようならの終了タグもインデントされていないのはなぜですか? 「ヘルパー」関数の「正しい」ローカル変数として保存しました。助けてくれてありがとう!

4

2 に答える 2

1

helper2 メソッドは、以下を含む文字列を出力します。

@@nl + '</goodbye>'

改行トークンと終了タグの間にインデントが収まらない方法はありません

于 2013-01-28T01:12:30.980 に答える
0

再帰的な方法が必要です。

@@tab  = '  '
@@nl   = "\n"
indent = 0

def helper3
    str =  'dawg'
end

def indented(p_indent, p_string='')
    @@tab * p_indent + p_string
end

def write_indented(p_indent, p_array)
    return indented(p_indent, helper3) if p_array.empty?
    head, *tail = p_array
    indent = indented(p_indent)
    indent + '<' + head + '>' + @@nl + 
            # recursive call :
        write_indented(p_indent + 1, tail) +
        @@nl + indent + '</' + head + '>'
end

tags = %w[hello goodbye]
puts write_indented(indent, tags)

実行 (ルビー 1.8.6):

$ ruby -w t.rb 
<hello>
  <goodbye>
    dawg
  </goodbye>
</hello>

残念ながら、再帰はほとんどの場合、階乗関数またはフィボナッチ関数によって説明されるため、理解がより困難になります。
再帰を呼び出しのカスケードで表すと、実際には非常に簡単です。

write_indented(0, ['hello', 'goodbye'])
    ...
    call write_indented(1, ['goodbye'])
       |
       |
       +--> ...
            call write_indented(2, [])
               |
               |
               +--> return if stop condition
                        |
               +<-------+
       +<------+ return   
       |
  <----+ returned value
end
于 2013-01-28T10:16:34.107 に答える