Translate

2013年8月17日土曜日

[perl]クラスメソッド

学習のため、某JavaのソースコードをPerlで表現してみる。


public class Counter {
    static int num = 0;
    static int getCounter(){
        return ++num;
    }                                                                              
}

実行してみる
public class SandBox extends Counter {
       public static void main(String[] args){
           System.out.println(Counter.getCounter());
           System.out.println(Counter.getCounter());
           System.out.println(Counter.getCounter());
           System.out.println("クラスフィールド:" + Counter.num);
       }
}

実行結果:
1
2
3
クラスフィールド:3


perlで表現してみます。
package Counter;
use strict;
use warnings;

our $num = 0;                                                                      

sub getCounter{
    return ++$num;
}

1;


use strict;                                                                        
use warnings;
use utf8;
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;
use Counter;

say Counter::getCounter();
say Counter::getCounter();
say Counter::getCounter();
say "クラス内変数:". $Counter::num;

実行結果:
1
2
3
クラス内変数:3

たいした違いはないですね。
クラス内の変数にアクセスするためにourで宣言しています。

[perl]複数のコンストラクタに対応するには?

学習のため、某JavaのソースコードをPerlで表現してみる。

Javaでは引数違い同名のメソッドを持つことができます。
便利ですね。

class Rectangle {
    int width;
    int height;
    Rectangle(){
        setSize(10, 20);
    }
    Rectangle(int w, int h){
        setSize(w, h);
    }    
    void setSize(int w, int h){
        width = w;
        height = h;
    }
    int getArea(){
        return width * height;
    }
}

引数無しのnewならデフォルト10, 20をセット
値があればそちらをセット同じことをPerlでやってみます。
処理をまねするならこうなるでしょうかねぇ?
package Rectangle;                                                                 
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

sub new{
    my $self  = bless{}, shift;

    #引数チェック
    if(@_==0){
        $self->setSize(10, 20);
    }elsif(@_==2){
        $self->setSize($_[0], $_[1]);
    }else{                                                                         
        die("コンストラクタは引数無し または、                                     
            2引数を指定してください(width, height)");
    }

    return $self;                                                                  
}

sub setSize{
    my $self = shift;
    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $self->{width}  = $_[0];
    $self->{height} = $_[1];
}

sub getArea{
    my $self = shift;
    return $self->{width} * $self->{height};
}

1;
引数を明示しない言語なので引数違いの同名メソッドは作れないので
引数の数で振り分けるしかないと思います。

実行してみます。
use strict;
use warnings;
use utf8;
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;                                                                     

my $r1 = Rectangle->new();
my $r2 = Rectangle->new(123, 5);

output($r1);
output($r2);

sub output{
    my $self = shift;
    say "幅 :". $self->{width};
    say "高さ:". $self->{height};
    say "面積:". $self->getArea();
}

実行結果:
幅 :10
高さ:20
面積:200
幅 :123
高さ:5
面積:615

[perl]コンストラクタで値の初期化

学習のため、某JavaのソースコードをPerlで表現してみる。

class Rectangle {
    int width;
    int height;
    Rectangle(){
        setSize(10, 20);
    }
    void setSize(int w, int h){
        width = w;
        height = h;
    }
    int getArea(){
        return width * height;
    }
}

引数無しでnewされた場合
setSizeメソッドを使って幅10, 高さ20を指定するわけですね。
では、やってみましょう。
package Rectangle;
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

sub new{
    my $class = shift;
    my $self  = bless {width=>0, height=>0}, $class;

    #引数無しでnewされたらデフォルト値を指定                                       
    if (@_==0){$self->setSize(10, 20)};                                            

    return $self;
}

sub setSize{
    my $self = shift;
    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $self->{width}  = $_[0];
    $self->{height} = $_[1];
}

sub getArea{
    my $self = shift;                                                              
    return $self->{width} * $self->{height};
}

1;

ポイントは第一引数にオブジェクトを渡すためには、blessした
オブジェクト経由でメソッドを呼ばないといけないというあたりですかね・・・
これで最初に書いたメソッドをうまく再利用できてますね。
では使ってみます。
use strict;
use warnings;
use utf8;
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;

my $r = Rectangle->new();
                                                                                   
say "幅 :". $r->{width};
say "高さ:". $r->{height};
say "面積:". $r->getArea();

出力結果:
幅 :10
高さ:20
面積:200


初期化の時は直接記載しようよ。
というのであれば、
class Rectangle {
    int width = 10;
    int height = 20;
    void setSize(int w, int h){
        width = w;
        height = h;
    }
    int getArea(){
        return width * height;
    }
}
こうなると思います。
では、Perlでは
package Rectangle;
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

sub new{
    return bless {width=>10, height=>20}, shift;
}                                                                                  

sub setSize{
    my $self = shift;
    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $self->{width}  = $_[0];
    $self->{height} = $_[1];
}

sub getArea{
    my $self = shift;
    return $self->{width} * $self->{height};
}

1;

Perlでクラスを書く

学習のため、某JavaのソースコードをPerlで表現してみる。

class Rectangle {
    int width;
    int height;
    void setSize(int w, int h){
        width = w;
        height = h;
    }
    int getArea(){
        return width * height;
    }
}

perlだとコンストラクタは必須なのでnewは書くとして
・値はsetSizeで指定する
・getAreaにて面積を求めあたいを返す
これを表現します。
package Rectangle;
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

sub new{
    return bless {width=>0, height=>0}, shift;
}
                                                                                   
sub setSize{
    my $self = shift;

    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $self->{width}  = $_[0];
    $self->{height} = $_[1];
}

sub getArea{
    my $self = shift;
    return $self->{width} * $self->{height};
}

1;
JavaやJavascriptと言った言語だと自動的にthisを参照すると自分自身のオブジェクトを参照できるけども
Perlだとshiftをすることで他の言語のthisの代わりのようなことができると。
つまり第一引数に自動的にオブジェクトがはいっているので取り出したら使えるよってことね。

ちなみに、blessのとこでJavaで言うとこのプロパティを用意しています。
使ってみます
use strict;
use warnings;
use utf8;  
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;

my $r = Rectangle->new();
$r->setSize(123, 45);

say "幅 :". $r->{width};
say "高さ:". $r->{height};
say "面積:". $r->getArea();

Perlのクラス作成 メモ

Perlのクラス作成について自分用のチートシート的にまとめておく

クラス作成で最小の状態は以下の通り
package クラス名;

sub new{
    return bless {}, shift;
}

1;




面積を求めるRectangleクラスを例に考える
コンストラクタでwidth と heightの値を設定し
getAreaで面積を求める

ファイル名:lib/Rectangle.pm
package Rectangle;
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

my ($width, $height);

sub new{
    return bless {}, shift;                                                        
}

sub setSize{
    my $self = shift;

    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $width  = $_[0];
    $height = $_[1];
}

sub getArea{
    my $self = shift;
    return $width * $height;
}

1;

ファイル:Sample.pl
use strict;                                                                        
use warnings;
use utf8;
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;

my $r = Rectangle->new();
$r->setSize(123, 45);
say $r->getArea();

2013年8月15日木曜日

Gitを一人で使うさいのメモ

■初期準備
git init



[WorkTree] → [Index] → [repository]

■Indexに追加
git add [file]指定したファイルをIndexに追加
git add .全てのファイルをIndexに追加する
git add -uCommit済みファイルのうち変更のあったものだけ追加
git add -pIndexへの追加を、変更箇所単位(ハンク)で追加
git add -Agit add . + git add -u



[WorkTree] ← [Index] ← [repository]
■Indexから削除
git reset HEAD [file]ステージへの登録を解除する


[WorkTree] → [Index] → [repository]
■コミット
git commit -m "内容"1行メッセージと共にコミットする



■バージョン管理下から除外する
git rm [file]バージョン管理下からはずし、ファイル自体も削除する
git rm --cached [file]バージョン管理下からはずす(ファイルは残す)



■状態の確認
git statusgitの状態を表示
git logコミットログを表示
git log -数字数字分コミットログを表示
git log -pコミットログにパッチ(差分情報)を追加して表示
git log --pretty=shortコミットログ(1行目の要約文のみ)を表示