Vino言語 (3/4) - やまざき@BinaryTechnology
「デスマーチと戦う武蔵流プログラマ やまざき のページ」

TopPage
(サイトマップ)


Book
(書籍)


「火事場プロジェクトの法則」
サポートページ


「LHAとZIP」
サポートページ



Document
(文章)

デスマーチの記録に見る
運命の分かれ道
NEW!

武蔵流プログラマからの提言

武蔵流プログラマが斬る Eclipse

コードデザイン最前線
1
2 3 4 5 6 7 8 9
10 11 12 13 ML

C++で読む
デザインパターン


ポインタ不要論

データ圧縮の基礎

プログラマへの
アドバイス


データ指向の話1 2

インターフェースの話


Diary & Books
(日記と本屋)

やまざきの
はてなダイアリ
(日記)
[] [PC] [資産運用]
[デスマ] [映画] [2足ロボ]

やまざきの本屋


SoftWorks
(ソフトウェア)


(1) DeepFreezer
(ディープ・フリーザー)
高速アーカイバ

(English Page)

(2) Closedown-Planet
(クローズダウン・プラネット)
アクションパズルゲーム


(3) PieceMaker
(ピース・メーカー)
ファイル分割/結合


(4) WakuPita
(枠ピタ)
ウィンドウ移動便利ツール

(English Page)

(5) ググ郎
(Bookmarklet)
選択文字列をGoogleで検索

NEW!


Developing
(開発中)


(1) DeepFreezer2
yz2dlg.dll alpha6


C Magazine特集yz2


Hobby & Favorite
(道楽/お気に入り)


2LegRobo
MindStorms



p.s.
(雑談)


Profile

i_want^^;


やまざきが書いた本


[システム開発]
火事場プロジェクトの法則
どうすればデスマーチをなくせるか?
2006/09/13 発売


LHAとZIP
圧縮アルゴリズム×プログラミング入門

奥村さんと共著です。
2003/12/01 発売


やまざきが寄稿した本


SEの読書術
「本質を読む」力を磨く10の哲学 2006/02発売。



開発の現場 Vol.002
「反デスマーチ大研究」という記事。2005/09/13発売。



Software People Vol.3
「武蔵流プログラマからの提言」という記事。2003/10/31発売。



Eclipse パーフェクトマニュアル vol.1
「武蔵流プログラマが斬る Eclipse」という記事。2003/06/05発売。




Vino言語(1/4) (2/4) (3/4) (4/4)


Vino 言語仕様の予定 ver. 0.02 2002/11/20

3章 クラス、インターフェース

おそらく、Vino の考え方で一番難しいと思われるところ。継承という概念ではなく、Java の interface に近いので、そう思っていただくと理解しやすいでしょう。

クラス Class

クラスの書き方は C/C++ とは大きく異なる。
class は関数(func)の延長であるという考え方であり、例えば、classのインスタンスとは、関数funcの戻り値と同じ意味になる。
よって、メンバを持たない class は、戻り値を持たない関数(func)と同じ意味になる。
out は C++/Javaでの public と同じような意味になる。

予約語 class out dtor
class class Foo       -- クラス Foo の定義文
{
    ...
}
end class Foo ; -- end はコメントのようなもの(省略できる)

◆まずは、簡単な例。

class class Foo       -- クラス Foo の定義文
{
    m_counter $ 0 ; -- メンバ

out func puts -- メソッド out は public の意味
    {
        sys.put( "{m_counter}\n" ) ;
        ++ m_counter ;
    }
}
end class Foo ;

foo : Foo() ; -- インスタンス生成 関数の呼び出しとほぼ同じ

sys.put( foo.m_counter ) ; -- NG コンパイルエラー(private参照不可)
foo.puts() ;              -- 0 を表示
foo.puts() ;              -- 1 を表示

sys.put( foo.type_name() ) ;      -- class:Foo{} を表示
sys.put( foo.Puts.type_name() ) ; -- func:Puts{} を表示

◆詳しく書くと

メンバはC++/Javaのメンバと同じようにカプセル化される。class内部で宣言された定数や変数はメンバとなる。
ただし、out 宣言しないとprivateとなり、classの外からアクセスできない。
また、func との違いは、dtor メソッド(デストラクタ)が書けること。というかfuncとclassの差はほとんどない。

class class Foo                -- クラス Foo の定義文
{
    in_a  : int in[0] ;  -- 引数(初期化時)関数の引数と同じように書く

    m_boo $ 100 ;        -- 変数や定数は、そのままメンバ変数になる(プライベート)

out m_foo : 200 ;        -- 定数(参照可能、public)
out m_woo $ 300 ;        -- 変数(更新可能、public)

    m_boo += in_a ;      -- コンストラクタの処理がいきなり書ける
    m_woo += in_a ;      -- コンストラクタの処理がいきなり書ける

out func foo             -- メソッド(関数)fooの書き方
    {
        in_a : in[0] ;   -- これはメソッドfooの引数
        out  : 1 ;       -- これはメソッドfooの戻り値

        .m_boo += 1 ;    -- メンバ変数にアクセス
        .m_woo += 1 ;    -- メンバ変数にアクセス
    }
    end func foo ;

    dtor              -- デストラクタ
    {
        ...           -- func では dtor は書けない
        .foo( 10 ) ;  -- メンバ関数にアクセス
    }
    end dtor ;
} ;                   -- end は省略

{
    a : Foo( 100 ) ;  -- 初期化引数 100(更新可能メンバ m_woo も更新不可)
    b $ Foo( 100 ) ;  -- 初期化引数 100(メンバ m_woo 更新可能)

    sys.put( a.m_boo ) ; -- NG コンパイルエラー(参照不可)
    sys.put( a.m_foo ) ; -- 200 を表示
    sys.put( a.m_woo ) ; -- 300 を表示
    a.m_foo ++ ;      -- NG コンパイルエラー(更新不可)
    a.m_woo ++ ;      -- NG コンパイルエラー(更新不可)
    b.m_foo ++ ;      -- NG コンパイルエラー(更新不可)
    b.m_woo ++ ;      -- 301

    sys.put( a.type_name() ) ; -- class:Foo{in:int,} を表示
    sys.put( b.type_name() ) ; -- $class:Foo{in:int,} を表示

} ; -- スコープが切れるところで、デストラクタが走る。


インターフェイス Interface

C/C++ にはインターフェースという構文は無い。Java にはあるが、Vino では使い方が少し違うので注意が必要。
Javaのinterfaceと同じだと思っていただいても良いです。ただ、記述の仕方が違います。
interface はインスタンスを生成できない。主に、クラスの中に取り込まれる形でインスタンスとなりその機能を発揮する。初期値は記述できまるが、メソッド(関数)の処理までは記述できない。

予約語 interface
interface interface _Foo       -- インターフェース _Foo の定義文
{
    ...
}
end interface _Foo ; -- end はコメントのようなもの(省略できる)

interface _Foo       -- インターフェイス _Foo の定義文
{
    in_a : int in[0] ; -- 引数(初期化時)

    m_boo $ 100 ;    -- NG privateな変数や定数は書けない。すべてpublicとして扱われる。

out m_foo : 200 ; -- OK 定数(外部から参照可能)
out m_woo $ 300 ; -- OK 変数(外部から更新可能)

    m_woo += in_a ;  -- NG 実行文は書けない

out func foo     -- メソッド(関数)の書き方
    {
        in,         -- fooメソッドの引数(型は何でもOK)
       in:int,     -- fooメソッドの引数(型はint固定)
        out:string, -- fooメソッドの戻り値(型は string )

        .m_woo += 1 ; -- NG 実行文は書けない
    }
    end func foo ;
}
end interface _Foo ; -- end はコメントのようなもの(省略できる)

class Foo     -- クラス Foo の定義文
{
use _Foo ; -- クラス Foo がインターフェイス _Foo を包含しているかチェック。
    ...
};

◆ interface の使い方(class に包含する普通の使い方)
interface interface _At       -- インターフェース _At の定義文
{
out func at{ in:int, out, } ; -- このメソッドがあること。
} ;

class Boo   -- クラス Boo の定義文
{
use _At ;   -- _At (at()メソッド)を包含しているかチェックするという意味
out func at -- このメソッドがあればOK。無いclassはコンパイルエラーになる。
    {
        in_a : int in [0] ;
        out : in_a * 3 ;
    } ;
} ;

class Foo    -- クラス Foo の定義文
{
use _At ;    -- _At (at()メソッド)を包含しているかチェックするという意味
out func foo -- at() メソッドでないのでNG。コンパイルエラー。
    {
        in_a : int in[0] ;
        out : in_a * 4 ;
    } ;
} ;

class Woo  -- クラス Woo の定義文
{
use _At ;
out func at
    {
        out : in[0] / 2 ;
    } ;
} ;

boo : Boo ;
foo : Foo ; -- NG
woo : Woo ;
sys.put( boo.at( 10 ) ) ;  -- 300 が表示される
sys.put( boo[ 1 ] ) ;      -- [] は .at() のシンタックスシュガーなので 3 が表示される
sys.put( woo.at( 7.0 ) ) ; -- NG 引数は int で宣言されている
sys.put( woo[ 7 ] ) ;      -- 3 が表示される

a $ _At boo ;       -- inertface名で変数インスタンスを作ることができる
sys.put( a.at( 5 ) ) ; -- 15 が表示される
a = woo ;           -- 変数インスタンスなので変更が可能
-- 厳密には違うがオブジェクト指向のポリモーフィズム(動的なバインド)のような機能を実現する
sys.put( a.at( 5 ) ) ; -- 2 が表示される

◆ interface内の定数の使い方(C++ のnamespaceのような使い方)
interface interface _Math
{
    m_pi : real 3.1415926535 ; -- π
    ...
} ;

r : 5.0 ;
circumference : 2.0 * _Math.m_pi * r ; -- inertface内の定数を直接参照できる
sys.put( circumference ) ; -- 31.1415926535 が表示される

◆ interface でコンテナ(配列)をつくる

おそらく、この考え方が Vino の一番の特徴になるのではないかと思う。
継承ではなくて、interface を使って、多態性(ポリモーフィズム)のような動作を実装する。
interface _Foo を含む boo や woo は vector[_Foo] に登録することができる。同じ _Foo であると解釈されるため、woo 特有の func something_gaa はアクセスできない。 interface _Foo に登録されている func do_something は boo と woo の区別無くアクセスできる。
interface
多態性
interface _Foo
{
out func do_something{} ; -- 何かをする(引数は無し)
} ;

boo : class Boo
{
use _Foo ; -- インターフェース_Foo を使う(チェックする)
out func do_something
    {
        sys.put( "boo\n" ) ; -- booを表示
    } ;
} ;

woo : class Woo
{
use _Foo ; -- インターフェース_Foo を使う(チェックする)
out func do_something
    {
        sys.put( "woo\n" ) ; -- wooを表示
    } ;

out func something_gaa -- interfaceに無いfuncも実装できる
    {
        sys.put( "gaa\n" ) ; -- wooを表示
    } ;
} ;

foo_tbl : vector[_Foo] boo, woo, boo, woo, ;
sys.put( foo_tbl.type_name() ) ;       -- vector[interface:_Foo{}] が表示される
sys.put( foo_tbl.size() ) ;            -- 4 が表示される
sys.put( foo_tbl[3].do_something() ) ; -- woo が表示される
sys.put( foo_tbl[0].type_name() ) ;    -- interface:_Foo{} が表示される

foo_tbl.each(
func {
    -- sys.put( in.type_name() ) ; -- interface:_Foo{} が表示される
    in.do_something() ; -- boo woo boo woo が表示される
} ) ;


以下、工事中


■4章 ライブラリ

標準ライブラリ sys
拡張ライブラリ Rex

◆ 省略時の引数(in) 引数の宣言を省略することができる。
sys と
Rex
sys.each( -- 標準入力から
func{
    -- sys.put( in.type_name() ) ; -- string が表示される
    line_str : in[0] ;
    r : Rex( '^From:' ) ; -- rex の ^ は正規表現で「先頭」と言う意味
    r.match( line_str, { sys.put( in[0] ) ; } ) ;
} ) ;

-- line_str, r を省略

sys.each(
func{
    Rex( '^From:' ).match in[0],
    {
        sys.put( in[0] ) ;
    } ;
} ) ;

◆ ファイルのアクセス(標準入出力のアクセス)
次のようにして、ファイルが書き込み可能かどうかなどを検査することができる。
File,
FileStatus
-- class File ファイル名で指定する
{
    fp $ File( 'file.txt' ) ;
    fp.write_open
    {
        in[0] <<= 'test ok' ;
    } ;
} ; -- デストラクタでファイルをクローズ

File( 'file.txt' ).write_open
{
    in[0] <<= 'test ok' ;
} ;

File( 'file.txt' ).read_open().each(
func {
    sys.put( in[0] ) ; -- in[0].type_name() : string
} ) ;

--- class FileStatus を用いた確認

status : FileStatus( 'file.txt' ) ;
status.read_ok ? sys.put( "読み込み可能\n" ) ;

class FileStatus では次のような検査が可能です。(UNIXでしか意味の無い物も多いです)
FileStatus read_ok -- 読み込み可能であれば(bool)
write_ok -- 書き込み可能であれば(bool)
exec_ok -- 実行可能であれば(bool)
size -- ファイルサイズを返す(int)
is_empty -- サイズが0であればtrue(bool)
is_file -- 通常ファイルであればtrue(bool)
is_dir -- ディレクトリであればtrue(bool)
is_link -- シンボリックリンクであればtrue(bool)
is_pipe -- 名前付きパイプであればtrue(bool)


4章の後半につづきます。



Vino言語(1/4) (2/4) (3/4) (4/4)

last update 2003/02/06
since 2002/09/16



やまざきのおすすめエレクトロニクス


やまざきのおすすめ本

やまざきのおすすめDVD

やまざきのおすすめCD



Copyright(c) 1998-2006.
YAMAZAKI Satoshi.
All rights reserved.

since 1997/12/15


このページのURLをメールで送る(友人・知人に教えてあげる)
このページを「お気に入り」に追加する(忘れないように…)
● お手紙はこちら↓。仕事の話は大歓迎です。(忙しくて返信できなかったらごめんなさい。)