Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@newta

Ceylonモジュール作成やクラスなどの基本コード

Ceylonのコードを書くときの基本的な書き方をやります。

まずはCeylonのプロジェクトが出来ている前提です。
出来ていない人は Ceylon環境の作り方からどうぞ。

まずモジュール作成

New > Ceylon Module
からモジュール作成のダイアログを開きます。
Module nameに入力した値はパッケージ名になります。
Runnable compilation unitに入力した値は実行のファイル名になります。

スクリーンショット 2013-12-04 13.25.04.png

上記のように入力して完了すると
以下のファイルが作成されます。
module.ceylon
package.ceylon
run.ceylon

module.ceylonにはモジュールで利用するライブラリなどの読み込み設定などを書くようです。
package.ceylonにはパッケージのドキュメントを書いたりするとこみたいです。
Javaでのpackage-infoみたいな感じ?
run.ceylon通常のCeylonソースコードを書いて行く場所です。

run.ceylonを開くと

shared void run() {    
}

と書かれているのでそのメソッドの中にバリバリ書いて行けばOKです!

クラスの作り方

と言うことでちょっとずつ実践的な感じにするために
絶対必須なクラス定義のしかた。

前回のCeylonの良いとこ説明コードその1で触れたとこは
特に説明しないのでvariableとかは前回の投稿を見てね。

と、言うことで早速クラス書いちゃいます。

shared void run() {

    value counter = Counter();
    print(counter.inc());  // -> 1
    print(counter.inc());  // -> 2
    print(counter.inc());  // -> 3
}

class Counter() {

    variable Integer i = 0;

    shared Integer inc() {
        return ++i;
    }
}

run.ceylonファイルに
Counterクラスを書いてみました。
なんとCounterクラスをインスタンス化するのにnewがありません!
最初は違和感があるけど、慣れればあんまり気になりません。

ただ、ちゃんと大文字からクラス名を付けないとクラス生成してるのか
メソッドを呼んでるのか分かんなくなりそう。

まあJavaをやっていれば既に雰囲気はつかんでると思います。

メソッド、公開変数、などのスコープ

Counterの保持する「i」はクラスの外には見えません。
クラス外に見えるようにするにはsharedを付けます。
protectedなスコープを持つ変数は定義出来ません。

次にincメソッドですがsharedがついているのでクラス外から呼び出すことが出来ます。
外すとクラス内からのみアクセス可能なメソッドになります。

最後にクラスにsharedを付けるとどこからでもクラスを参照することが出来ます。
何も付けていないときは同じパッケージ内の場所からのみ参照出来ます。
ファイルが別でもパッケージが同じであれば参照可能です。

Javaのprotectedとパッケージプライベートの扱いって微妙でしたよね。。
どう使っていいか困ったこともあります。。
でも、Ceylonでは完全に割り切ってる感じでシンプルだなと。

デフォルト引数

Ceylonではメソッドにはデフォルト引数が使えます。
incメソッドに引数に与えた数値分増加出来るようにしてみました。

    shared Integer inc(Integer add=1) {
        return (i += add);
    }

デフォルト引数が可能にはなっていますが、
代わりにJavaでは出来たメソッドのオーバーロードが出来なくなっています。

ま、良いんじゃないかな。デフォルト引数値はC#やScalaを指くわえながら見て
欲しいなーと思っていたのであった方がいいよね!

コンストラクタ

まず、クラスがメンバを持つ場合、全て初期化しないとコンパイルエラーとなります。
今回は i に 0 をセットしてます。

この辺もCeylonの細やかな厳しさを感じる。
Javaにグッときてる人は逆にいいんじゃないかなと思う。

ここではコンストラクタでカウンターの初期値を設定して生成出来るようにしてみましょう。


class Counter(variable Integer i=0) {

    shared Integer inc(Integer add=1) {
        return (i += add);
    }
}

はい。メンバ変数で定義してたヤツが居なくなりました!
なんと、コンストラクタで引数として受け取った変数は
自動でメンバ変数として保持されます。
外部から参照されるようにしたい場合はこの「i」にsharedを付ければ
クラス外から参照出来るようになります。

ちょっと楽チン。

コンストラクタで何かチェックしたいときは
そのままコードを書けばOK.
初期値としてマイナスの数値が入った場合エラーにするようにすると


class Counter(variable Integer i=0) {
    assert(i>-1);

    shared Integer inc(Integer add=1) {
        return (i += add);
    }
}

こんな感じ。
マイナス値のときに自動で0にしちゃうようにしてみると

class Counter(variable Integer i=0) {

    if(i < 0) {
        i = 0;
    }

    shared Integer inc(Integer add=1) {
        return (i += add);
    }
}

こんな感じ。
メソッドなしでロジックやら初期変数が定義されたりですね。

複雑なコンストラクタが生まれるよりは1個のコンストラクタに集約されて
記述も身軽になって良いかも??

でもこの辺はJavaと感覚がちょっと違う感じかなぁ。
ここは使い込んでみないと良いのか悪いのか分からないかも。

setterとgetter

setterとgetterの扱いが変わっています。
Javaでは命名規則でsetXxxxx、getXxxxというメソッドが
プロパティのsetter、getterと言う扱いでしたが、
Ceylonでは以下のように宣言します。

    shared Integer nowCount {
        return i;
    }

    assign nowCount {
         i = nowCount;
    }

getterは値を返すだけのものを付ければOKです。
この宣言は参照は出来ても代入は出来ません。
代入するにはsetterの宣言が必要です。
参照はこのように呼び出してコンソールに出力したり出来ます。

print(counter.nowCount);

setterはassignで宣言します。sharedは必要ありません。
assignを付けると自動的に公開状態になります。
以下のように代入で呼び出すことが出来ます。

counter.nowCount = 10;

ちなみに1行のときはこんな感じで書くことが出来ます。


    shared Integer nowCount => i;


    assign nowCount => i = nowCount;

やばいscalaっぽくなってきた。
でも、Java8も来そうだし、アリですよね!

Javaでの宣言との比較

java -> ceylon
public -> shared
protected -> メソッドは無印で同じパッケージからアクセス可能
private -> 変数は無印でクラス内からでのみアクセス可能

コンストラクタは1つだけ!
デフォルト引数値を指定出来るようになった!

gettersetterはメソッド命名規則ではなくassignでsetterを、getterは別参照名で。

まとめ

Javaと書き方が違うなーって感じるところもちょいちょい出てきました。
でも、Javaで微妙だ・・・って思っていたところが順々に改善されている感じが分かります。

スコープ、そしてデフォルト引数とsetter、getterそしてコンストラクタでした。
改善されているなぁ。

読み口はあまり変わらないまま読めるかなーと思います。

まあ、コンストラクタ内での処理とか、getterとsetter周りでは
scalaとか読んでればあんまり違和感無いかも知れないけど
Javaから見るとちょっと違和感が出てきたかも?

それでもJavaっぽい読み味は失われてません!
でも、ちょっと慣れが必要になって来る文が出てきたかも。

もうちょっとだけ頑張ってみて!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?