hitode909の日記

以前はプログラミング日記でしたが、今は子育て日記です

Perlで自動でセミコロン書くやつ

セミコロン書きたくないから,Perlで自動でセミコロン書くやつを作った.


こういうセミコロンなしのFizzBuzzPerlのプログラムを書いて,

#! /usr/bin/env perl
use strict
use warnings

for my $i (1..20) {
    my $message = ""
    $message .= "Fizz" unless $i % 3
    $message .= "Buzz" unless $i % 5
    $message = $i unless $message
    print "$message\n"
}


perl_auto_semicolonというコマンドにファイルを渡すと,

% ./perl_auto_semicolon fizzbuzz.pl


コンパイル通るまで行末にセミコロンつけたり外したりして,うまく動きそうになると,ファイルに書き出してくれる.
下が出力されたソースコードで,いい感じにセミコロンがついてる.

#! /usr/bin/env perl
use strict;
use warnings;

for my $i (1..20) {
    my $message = "";
    $message .= "Fizz" unless $i % 3;
    $message .= "Buzz" unless $i % 5;
    $message = $i unless $message;
    print "$message\n"
}


実行すると,ちゃんとFizzBuzzが出る.

% perl out.pl
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz


セミコロンつける場所を探すスクリプトはRubyで書いてある.

#! /usr/bin/env ruby
file = ARGV.first

code = open(file).read

def append_semicolon(code, time)
  code.split(/\n/).each_with_index.map{|line, num|
    time[num] == 1 ? line + ";" : line
  }.join("\n")
end

(1.upto 1.0/0).each{ |i|
  system "clear"
  new_code = append_semicolon(code, i)
  puts new_code
  puts
  puts
  system("echo '#{new_code}' | perl -wc")
  if $? == 0
    puts "created out.pl"
    open("out.pl", "w"){ |f|
      f.write new_code
    }
    exit
  end
}


全通り順番にセミコロンをつけたり外したりして,perl -wcに渡してコンパイルできるか調べている.
これくらいの行数で10秒くらいかかる.
大規模なソフトウェアに適用する場合は,深夜にバッチで実行すればいいと思う.


意味ないと思うけどいちおうGitHubにも置いてある.


というのをKyoto.pmで発表した.