Skip to content

fix: escape control characters in Ruby code generation #28

@takaokouji

Description

@takaokouji

概要

コミット 89096a4 で print, puts, p を命令ブロックに変換できるようになりました。しかし、コントロール文字(\n, \t など)を含む文字列を変換後、再度 Ruby に変換すると、コントロール文字が改行やタブとして出力されてしまう問題があります。

問題の詳細

現在の動作

# Ruby コード
print("Hello, Ruby.\n")

↓ Blocks に変換

looks_say ブロック (MESSAGE: "Hello, Ruby.\n" - 改行文字として格納)

↓ Ruby に変換

# 改行がそのまま出力される
print("Hello, Ruby.
")

期待される動作

# エスケープシーケンスを保持
print("Hello, Ruby.\n")

原因

src/lib/ruby-generator/index.jsquote_() メソッド(行334-349)で、コントロール文字のエスケープ処理が不足しています。

現在の escapeChars_ オブジェクト:

RubyGenerator.escapeChars_ = {
    '"': '\\"',
    '\\': '\\\\'
};

問題: \n, \t などのコントロール文字がエスケープされていません。

解決策

実装内容

quote_() メソッドを拡張し、以下のコントロール文字をエスケープシーケンスに変換します:

文字 エスケープ後 説明
\n \\n 改行
\t \\t タブ
\r \\r 復帰
\b \\b バックスペース
\f \\f 改ページ
\v \\v 垂直タブ
\0 \\0 NULL

実装箇所

ファイル: src/lib/ruby-generator/index.js

RubyGenerator.escapeChars_ = {
    '"': '\\"',
    '\\': '\\\\',
    '\n': '\\n',
    '\t': '\\t',
    '\r': '\\r',
    '\b': '\\b',
    '\f': '\\f',
    '\v': '\\v',
    '\0': '\\0'
};

テストケース

ファイル: test/unit/lib/ruby-generator/looks.test.js

改行やタブを含む文字列のテストケースを追加:

test('print with newline character', () => {
    const block = {
        id: 'block-id',
        opcode: 'looks_say',
        inputs: { MESSAGE: {} }
    };
    RubyGenerator.cache_.comments['block-id'] = { text: '@ruby:method:print' };
    RubyGenerator.valueToCode = jest.fn().mockReturnValue('"Hello, Ruby.\\n"');
    const expected = 'print("Hello, Ruby.\\n")\n';
    expect(RubyGenerator.looks_say(block)).toEqual(expected);
});

test('puts with tab character', () => {
    const block = {
        id: 'block-id',
        opcode: 'looks_say',
        inputs: { MESSAGE: {} }
    };
    RubyGenerator.cache_.comments['block-id'] = { text: '@ruby:method:puts' };
    RubyGenerator.valueToCode = jest.fn().mockReturnValue('"Hello\\tRuby"');
    const expected = 'puts("Hello\\tRuby")\n';
    expect(RubyGenerator.looks_say(block)).toEqual(expected);
});

影響範囲

quote_() メソッドはすべての文字列リテラル生成に使用されているため、以下にも影響します:

  • say, think ブロック
  • 変数の初期値
  • リストの要素
  • メソッドの引数

確認が必要: 既存のテストが壊れないか確認する必要があります。

完了条件

  • escapeChars_ にコントロール文字を追加
  • テストケースを追加(改行、タブなど)
  • 既存のテストがすべて通ることを確認
  • Lint チェックが通ることを確認
  • 統合テストでの動作確認

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions