Perl, Python, Ruby比較
| 目次 |
[編集]はじめに
以下のバージョンで記述しているつもりです
- perl 5系
- python 2.6系
- ruby 1.9系
ある言語で記述しておきたいと思った時に記入し、その時点で他の言語は空白にしています。
別のタイミングで確認してから記入しているので、空白の項目があります。
誤りもあると思います。
本サイトは、思い出すためのきっかけですので「きっかけ」として利用して下さい。
[編集]入口
| 概要 | Perl | Python | Ruby |
| 標準拡張子 | .pl | .py | .rb |
| Hello World | print 'Hello World!'; print "Hello World!\n" | from sys import stdout stdout.write("Hello World!") print "Hello World!" | print 'Hello World!' puts 'Hello World!' print "Hello World!\n" p "Hello World!" |
| コメント | # =アルファベット ... =cut | # """ ... """ | # =begin ... =end |
| エンコード指定(utf-8) | #!/usr/bin/perl use utf8; | #!/usr/bin/python # coding: utf-8 | #!/usr/bin/ruby # coding: utf-8 |
| $ ruby -Ku スクリプト名 | |||
| 構文チェック | $ perl -wc (スクリプトファイル名) | $ pychecker (スクリプトファイル名) ※別途インストールの必要あり | $ ruby -wc (スクリプトファイル名) |
| デバッグ | $ perl -d (スクリプトファイル名) | $ pdb (スクリプトファイル名) | $ ruby -r debug (スクリプトファイル名) |
[編集]変数
| 概要 | Perl | Python | Ruby |
| コマンドライン&引数 | print ARGV[0]; | # [0]は、スクリプト名 import sys print(sys.argv[1]) | p ARGV[0] |
| プログラム名 | print $0 | print(sys.argv[0]) | p $0 |
| 変数への代入 | $var = 10 | var = 10 | var = 10 # グローバル変数 $var = 10 |
| 多重代入 | ($s1, $s2) = ('1', '2'); | s1, s2 = '1', '2' | s1, s2 = '1', '2' |
| null | undef if(defined($var)){ # 代入されている } | None | nil |
[編集]true, false
| 概要 | Perl | Python | Ruby |
| 概要 | - | - | false,nil : false それ以外 : true |
| true(True) | - | true | true |
| false(False) | - | false | false |
| 0(int) | false | false | true |
| 1(int) | true | true | true |
| null | false(null) | false(None) | false(nil) |
| '' | false | false | true |
| '0' | false | true | true |
| undefined | false | - | - |
[編集]組み込み型
| 概要 | Perl | Python | Ruby |
| 数値 | $var = 10; $var = 1.23; $var = 0x20; | var = 10 var = 1.23 var = 0x20 | var = 10 var = 1.23 var = 0x20 |
| 文字列 | $var = "abc\n"; $var = 'abc'; $var = '日本語'; | # ' " の扱いは同じ var = "abc\n" var = r"abc" var = u'日本語' | var = "abc\n" var = 'abc' var = '日本語' |
| 配列 | @var = (1,2,3); @var = ('あ', "い\n", 3); print $var[0]; print '' . @var; | # リストと呼ばれる var = [1,2,3] var = [u'あ', u"い\n", 3] print(var[0]) print(len(var)) | var = [1,2,3] var = ['あ', "い\n", 3] p var[0] p var.size |
| タプル | - | # 書換不可能なリスト var = (1,2,3) var = (u'あ', u"い\n", 3) print var[0] | - |
| 集合 | - | # set型 var = set([1,2,3]) var = set((1,2,3)) add(),remode()等により操作出来ます | # set オブジェクト require 'set' var = Set.new [1,2,3] p var.include? 2 #=> true |
| ハッシュ | %var = ('one' => '一', 'two' => '二'); print val['one']; | # 辞書と呼ばれる var = {'one': u'一', 'two': u'二'} print(val['one']) | val = {'one' => '一', 'two' => 'ニ'} p val['one'] # シンボルオブジェクト val = {one: '一', two: 'ニ'} p val[:one] |
[編集]演算子
| 概要 | Perl | Python | Ruby |
| 論理演算 | !, &&, || (not, and, or, not : 優先順位 低) | and, or, not | !, &&, || (not, and, or, not : 優先順位 低) |
| +-×÷除 | +, -, *, /, % | +, -, *, /, % | +, -, *, /, % |
| ビット演算 | |, &, ^ | |, &, ^ | ~, |, &, ^ |
| シフト演算 | <<, >> | <<, >> | <<, >> |
| 比較(数値) | ==, !=, <, >, <=, >= | ==, !=, <, >, <=, >= | ==, !=, <, >, <=, >= |
| 比較(文字) | eq, ne, lt, gt, le, ge | ||
| 累乗 | ** | ** | ** |
| 複合演算子 | +=, -= | +=, -= | +=, -= |
| === | - | - | 比較よりも緩い(caseは ===) ・数値,文字列の場合 == と同じ ・正規表現の場合 =~ と同じ |
[編集]文字列
| 概要 | Perl | Python | Ruby |
| 文字連結 | var = 'abc' . 'def'; | var = 'abc' + 'def' | var = 'abc' + 'def' |
| $var = join('', 'abc', 'def'); | var = ''.join(['abc','def']) | var = ['abc', 'def'].join('') | |
| abc = 'abc' def = 'def # abc が書き換え得られる abc << def << 'ghi' | |||
| abc = 'abc' def = 'def # abc が書き換え得られる abc.concat(def).concat('ghi') | |||
| 文字列の掛算 | $var = ' ' x 20; | var = ' ' * 20 | var = ' ' * 20 |
[編集]進数表記
| 概要 | Perl | Python | Ruby |
| 2進数 | 0b1101 | int('0101', 2) 0b1101 # 3.0 | 0b1101 |
| 8進数 | 0123 | 0123 | 0123 |
| 16進数 | 0xffff | 0xffff | 0xffff |
| 16進数文字→10進数数値 | var = hex('30'); | ||
| 16,8,2進数文字→10進数数値 | var = oct('0x30'); var = oct('030'); var = oct('0b1101'); |
[編集]エスケープシーケンス
| 概要 | Perl | Python | Ruby |
| 改行(LF) | \n | \n | \n |
| CR | \r | \r | \r |
| タブ | \t | \t | \t |
| ' | \' | \' | \' |
| " | \" | \" | \" |
| raw文字 | q/.../, '...' | r"C:\temp\a.txt" | %q/.../, '...' |
[編集]条件分岐
| 概要 | Perl | Python | Ruby |
| if | if(val eq 'if'){ print 'if'; } elsif(val eq 'elsif'){ print 'elsif'; } else { print 'else'; } | if val == 'if': print('if') elif val == 'elif': print('elif') else: print ('else') | if val == 'if' then p 'if' elsif val == 'elsif' then p 'elif' else p 'else' end |
| 処理 if() | print('true') if(val eq 'val1'); | - | print('True') if val == 'val1' |
| unless | unless(val ne 'if'){ print 'else'; } else { print 'if'; } | - | unless val != 'if' p 'else' else p 'if' end |
| switch case | - | - | case val when 1 then p 'number' when 'str2' then p 'string' when 1..3 then p 'range' when /^$/,/^[yY]/ then p 'regex' else p 'else' end |
[編集]繰り返し
| 概要 | Perl | Python | Ruby |
| for | for($i = 0; $i < 10; $i++){ print $i; } | for cnt in range(0,10): print(cnt) | for cnt in 0..9 p cnt end |
| foreach | @array = ('a','b'); foreach $val (@array){ print $va; } # %hash = ('a' => 'one', 'b' => 'two'); foreach (values %hash){ print; } | hash = {"a": "one", "b": "two"} for key in hash.keys(): print key | hash = {'a' => 'one', 'b' => 'two'} hash.each{|key, val| p key } # または for key,val in hash p key,val end |
| while | while($cnt < 5){ print $cnt; $cnt++; } | while cnt < 5: print(cnt) cnt += 1 | while cnt < 5 p cnt cnt += 1 end |
| until | until(!($cnt < 5)){ print $cnt; $cnt++; } | - | until !(cnt < 5) p cnt cnt += 1 end |
| times | - | - | # 10回ループ 10.times{ |t| p t, 'times' } # または 10.times do |t| p t, 'times' end |
| loop | - | - | loop { p '無限ループ' } |
| break continue 同じ条件繰返し | last; next; redo; | break continue | break next redo |
[編集]ファイル入出力
| 概要 | Perl | Python | Ruby |
| オープン | open(キー,'< readme.txt') || die 'エラー'; | import codecs; f = codecs.open("readme.txt", "r", "shift-jis") f = open("readme.txt", "r") モード: r,w,a,r+,w+,a+ Universal Newline Support: U | f = open("readme.txt", "r") モード: r,w,a,r+,w+,a+ |
| 読み込み | while(<キー>){ # $_ } | d = f.read() d = f.readline() d = f.readlines() | d = f.gets d = f.readlines() |
| 書き込み | print キー, 'データ'; | f.write(d) f.write(シーケンス) | f.write(d) |
| クローズ | close(キー); | f.close() | f.close |
| その他 | - | - | # 自動close open("readme.txt", "r"){ |f| while line = f.gets end } |
[編集]関数の定義
| 概要 | Perl | Python | Ruby |
| 一般形式 | sub func($$){ my ($arg1, $arg2) = @_; print $arg1 . $arg2; } | def func(arg1, arg2): print(arg1 + arg2) | def func(arg1, arg2) p arg1, arg2 end |
| デフォルト引数 | sub func{ my ($arg1, $arg2) = @_; $arg2 = defined($arg2) ? $arg2 : 'def'; print $arg1 + $arg2; } | def func(arg1, arg2="def"): print(arg1 + arg2) | def func(arg1, arg2='def') p arg1, arg2 end |
| 戻り値 | sub func($$){ return @_; } | def func(arg1, arg2): return arg1 + arg2 | def func(arg1, arg2) # return を記述しない方が普通 return arg1 + arg2 end |
| 可変長引数 | sub test($$@){ my ($arg1, $arg2, @arg3s) = @_; } | def func(arg1, arg2, *arg3s): # arg3sはタプルとして処理 def func(arg1, arg2, **arg3s): # arg3sは辞書として処理 | def func(arg1, arg2, *arg3s) # arg3s は配列として処理 end |
| 関数の ポインタ | # サブルーチンリファレンス sub func { print "call!"; } # リファレンス my $ref_func = \&func; # 呼び出し &$ref_func(); #= $ref_func->(); | ||
| 無名関数の ポインタ | # 無名サブルーチンリファレンス $ref_func = sub { print "call!"; }; # 呼び出し &$ref_func(); #= $ref_func->(); |
[編集]関数
| 概要 | Perl | Python | Ruby |
| 文字列長 | $ln = len('123'); | ln = len('123') | ln = '123'.length |
| split | @val = split(',', '1,2,3'); | val = "1,2,3".split(",") | val = "1,2,3".split(",") |
| join | $val = join(',', ('1','2','3')); | val = ["1","2","3"].join(",") | val = ['1','2','3'].join(',') |
[編集]正規表現
| 概要 | Perl | Python | Ruby |
| マッチ | # $_ = 検索文字列 if(m/パターン/){ # 結果あり } | import re if re.match(r"パターン", 検索文字列): # 結果あり | if /パターン/ =~ "検索文字列" # 結果あり end |
| 置き換え | # $_= 置き換え文字 s/前/後/; s/前/後/g; # 結果 $_ | import re val = re.sub(前, 後, 置き換え文字,1) val = re.sub(前, 後, 置き換え文字) | val = 置き換え文字.sub(/前/,後) val = 置き換え文字.gsub(/前/,後) |
| グループ | # $_ = 検索文字列 m/パターン/; $1 $2 | import re p = re.search(r"パターン", 検索文字列) val = p.group(1) val = p.group(2) | /パターン/ =~ "検索文字列" $1 $2 |
[編集]パッケージ(Perl)・モジュール(Python,Ruby)
| 概要 | Perl | Python | Ruby |
| 読み込み | require 'ファイル名'; use 'パッケージ名'; | import モジュール名 from クラス名 import メソッド from クラス名 import * | require "ファイル名" (.rbは省略可) include モジュール名 |
| 検索順 | 1. カレントディレクトリ 2. 環境変数PYTHONPATH 3. 標準ライブラリパス 4. site-packages | ||
| 検索順表示 | # perl -V でも見る事が出来る foreach $val (@INC){ print $val . "\n"; } | import sys print sys.path | puts $LOAD_PATH # または puts $: |
| 検索パス 追加方法 | # 下の方が優先(順位が上となる) 1. PERL5LIBにコロン区切りで追加 2. perl -I 指定 3. unsift(@INC, 'パス'); | # 下の方が優先(順位が上となる) 1. RUBYLIBにコロン区切りで追加 2. ruby -I 指定 3. $LOAD_PATH.unshift 'パス' | |
| 作成 | package パッケージ名; ... | 通常のスクリプトファイル作成 | module ModuleName ... end |
| 初期処理 | BEGIN{ ... # コンパイル中でも直ちに実行 } | BEGIN{ ... } | |
| 終了処理 | END{ ... # 異常終了しても実行 } | END{ ... # 異常終了時実行されない } | |
| 自動ロード | # 指定関数が定義されていない場合 sub AUTOLOAD{ ... # 関数名: $AUTOLOAD, 引数: @_ } | ||
| 定数 | # 利用方法 # PakageName::CONST_VALUE package PackageName; use constant CONST_VALUE => 1; | - | # 利用方法 # ModuleName::CONST_VALUE module ModuleName CONST_VALUE = 1 ... end |
| メソッド | - | - | # 利用方法 # ModuleName.method(arg1, arg2) def method(arg1, arg2) ... end module_function :method |
[編集]オブジェクト指向
[編集]クラス
| 概要 | Perl | Python | Ruby |
| 生成 | $obj = new ClassName($arg1, $arg2); $obj = ClassName->new($arg1,$arg2); | obj = ClassName(arg1, arg2) | obj = ClassName.new(arg1, arg2) |
| 定義 | package ClassName; ... 1; | class ClassName(object): # pass | class ClassName ... end |
| 定義 (継承) | # ClassName 内にメソッドが存在しなければ # @ISA内のメソッドを利用する package ClassName; @ISA = qw(SuperClass); # または package ClassName; use base qw(SuperClass); | class ClassName(SuperClass): # pass | class ClassName < SuperClass ... end |
| 定義 (多重継承) | # 多重継承:可能 @ISA = qw(SuperClass SupserClass2); use base qw(SuperClass SuperClass2); | # 多重継承:可能 class ClassName(SuperClass, SuperClass2): | # 多重継承:不可 # Mix-Inで実現 module SuperClass2 end class ClassName < SuperClass1 include SuperClass2 end |
[編集]メソッド
| 概要 | Perl | Python | Ruby |
| コンストラクタ | sub new($$$){ my($pkg, $arg1, $arg2) = @_; return bless { 'v1' => $arg1 , 'v2' => $arg2 }, $pkg; } | def __init__(self, arg1, arg2): ... | def initialize(arg1, arg2) ... end |
| コンストラクタ(継承) | sub new($$$){ my($pkg, $arg1, $arg2) = @_; return $pkg->SUPER::new($arg1, $arg2); } | def __init__(self, arg1, arg2): SuperClass.__init__(self, arg1, arg2) | def initialize(arg1, arg2) super(arg1, arg2) end |
| デストラクタ | # 省略可能だが AUTOLOAD は呼ばれる sub DESTROY{ my($self) = @_; ... } | # 省略可能 def __del__(self): | # ObjectSpace.define_finalizer の利用 |
| インスタンス メソッド | # $obj->method(...); sub method($$$){ my($self, $arg1, $arg2) = @_; ... } | def method(self, arg1, arg2): ... | def method(arg1, arg2) ... end |
| クラス メソッド | # パッケージ名->method(...) sub method($$){ my($arg1, $arg2) = @_; ... } | # 利用時 # (1)クラス名.メソッド名 # (2) クラス名::メソッド名 1. def ClassName.method(arg1, arg2) 2. class << ClassName def method(arg1, arg2) 3. def self.method(arg1,arg2) | |
| デフォルトのアクセス制限 | public | public | public |
| public | sub | def pub ... end public :pub # または public 以降 | |
| private | # 呼び出し &$pri('msg'); my $pri = sub ($){ my ($msg) = @_; print $msg . "\n"; }; | # 属性・メソッドに _ または __ を先頭に付加します。 # アクセス制限させたい場合は、__ を利用します。 | # 呼び出し pri('msg') def pri(msg) print msg + "\n" end private :pri # または private 以降 |
| protected | def pro ... end protected :pro # または protected 以降 |
[編集]変数、プロパティ、定数
| 概要 | Perl | Python | Ruby |
| クラス変数 | package ClassName # use vars qw($var); our $var = 1; sub func($){ $var = 1; } | class ClassName: var = 1 def func(self): ClassName.var = 1 | class ClassName @@val = 1 def func @@val = 1 end end |
| インスタンス 変数 | sub func($$$){ my($self, $arg1, $arg2 ) = @_; $self->{'val'} = 1; } | def func(self, arg1, arg2): self.val = 1 | def func(arg1, arg2) @val = 1 end |
| プロパティ | sub val{ my $self = shift; @_ && ($self->{_val} = shift); return $self->{_val}; } | def getx(self): ... def setx(self): ... val = property(getx, setx) val = property(getx) | # getter attr_reader :val # setter attr_writer :val # getter&setter attr_accessor :val # def val return @private_val end def val=(value) @private_val = value end |
| 定数 | # 利用方法 # ClassName::CONST_VALUE package ClassName; use constant CONST_VALUE => 1; our $CONST_VALUE; *CONST_VALUE = \1; | - | # 利用方法 # ClassName::CONST_VALUE class ClassName CONST_VALUE = 1 end |
[編集]例外処理
| 概要 | Perl | Python | Ruby |
| catch finally | eval{ print "eval test\n"; }; $err_msg = $@; # finally 処理 if($err_msg){ # undef: false # 例外処理 $@:例外メッセージ } | try: ... except (例外クラス名 変数名): ... else: ... finally: ... | begin ... rescue => ex print(ex.message) ensure ... # retry end |
| raise | die "例外メッセージ"; (Carp::croak) | raise "例外メッセージ" raise ExError("例外メッセージ") | raise "例外メッセージ" raise ExError("例外メッセージ") |
| 主な例外 | # 例外文字列 | NameError AttributeError TypeError IndexError KeyError IOError ZeroDivisionError | RuntimeError SecurityError NameError IOError SystemCallError |
[編集]変換
| 概要 | Perl | Python | Ruby |
| 文字→数値 | var = int('123') var = floar('123.4') | var = '123'.to_i var = '123.4'.to_f | |
| 文字→数値コード | # 先頭の文字('1')を文字コードに $var = ord('123'); #= 49(十進) | # 先頭の文字('1')を文字コードに var = '123'.ord #=> 49(十進) | |
| 数値→文字 | var = str(123) | var = 123.to_s | |
| 数値コード→文字 | $var = chr(0x30); | var = 0x30.chr |
[編集]標準ライブラリ
| 概要 | Perl | Python | Ruby |
| 日時 | localtime | date() time() | Time.now |
| 環境変数 | ENV{'変数名'} | e = environ() e.getenv() e.putenv() | ENV['変数名'] |
| ファイル ディレクトリ | chdir use Cwd; print Cwd::getcwd(); mkdir rmdir unlink rename | chdir() getcwd() mkdir() rmdir() remove() rename() | Dir.chdir() Dir.pwd Dir.mkdir() Dir.rmdir() File.delete() File.rename() |
[編集]その他
| 概要 | Perl | Python | Ruby |
| 演算子のオーバーライド | use overload '+' => \&add, '-' => \⊂ | def __add__(self, val) __sub__, __mul__, __div__ __and__, __or__ __cmp__, __eq__, __ne__, __lt__, __gt__ | def +(other) -(other), *(other), /(other) +@, -@, [](index), []=(index) |
| DATA __END__ | while(<DATA>){ chomp(); print $_ . "\n"; } __END__ ... | _ | DATA.each{ |line| line = line.chomp print(line, "\n") } __END__ ... |
| ヒアドキュメント | $var = <<"記号"; ... 記号 | var = """... ... """ | var <<"記号" ... 記号 # セパレータの前にスペースOK var <<-"記号" ... 記号 |
| シグナル | $ref_sigfunc = sub { print "Signal!\n"; }; $SIG{"INT"} = $ref_sigfunc; sleep(10) | import signal from time import sleep def sigfunc(num, frame): print "Signal!" signal.signal(signal.SIGINT, sigfunc) sleep(10) | Signal.trap(:INT){ puts "Signal!" exit(0) } sleep(10) |
| クロージャ | sub closure_test($){ my $val = shift(@_); my $count = 0; return sub($$) { my ($arg1, $arg2) = @_; print $arg1 . $arg2; print $count++ . "$val\n"; }; } my $ref_closure = closure_test('test'); #=> data:1:0test &$ref_closure('data', ':1:'); #=> data:2:1test &$ref_closure('data', ':2:'); | def closure_test(val): count = [0] # 0 : shallow copy def __closure_test(arg1, arg2): print arg1 + arg2 + \ str(count[0]) + val count[0] += 1 return __closure_test closure = closure_test("test") # data:1:0test closure("data", ":1:") # data:2:1test closure("data", ":2:") | def closure_test(val) count = 0 return lambda { |f_arg1, f_arg2| print f_arg1 + f_arg2 puts count.to_s + val count += 1 } end closure = closure_test('test') #=> data:1:0test closure.call('data', ':1:') #=> data:2:1test closure.call('data', ':2:') |
| リファレンス | 「リファレンス」 参照 | - | - |
| シンボリックリファレンス | 「シンボリックリファレンス」 参照 | - | - |

