指向性メモ::2006-07-15::それAdaならできるよ

ページ情報
制作日
2006-07-15T14:18:57+09:00
最終更新日
2006-07-16T16:40:12+09:00
ページ内目次

それ、Adaならできるよ。略して「それいだ」(何

Adaなら83の時代から部分集合余裕だぜー。ていうか、JavaってなんでJ2SE5まで列挙型なかったんだろね。気持ちは何となく分かるけども。

Ascii_StringString型がまんまだし、Non_Negative_IntegerもやっぱりPositive型が最初からIntegersubtypeとして定義されているのでそれを使えばよし。

Scoreはこんな感じかな。派生型を使ってIntegerとの演算を禁止してるけど、状況によってはやり過ぎかも。どうせならScore_nも派生型にして、100と1000の間での演算を禁止してもいいかな。めんどくさい場合はIntegersubtypeにしちゃえば、型変換が不要なので楽ちん。

type Score is new Integer range 1 .. Integer'Last;
subtype Score_100 is Score range Score'First .. 100;
subtype Score_1000 is Score range Score'First .. 1000;

で、ふと気がついたんだけど、

type Non_Negative_Integer renames Positive;

って認められないのね。普通使わないからいいけど、packageをrenamesできるんだから、typeでもできるといいな。


次、UserIDの話。

Ada95は勉強中だから若干自信ないけど、インスタンス変数の実際のところであるtagged recordはどうやらrecordと同じく要素の内容を実行時に変化できるらしいので、こんな感じで行ける。Javaでいうとコンストラクタ次第でインスタンス変数が変化する感じ? なのかな。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Sample is

   package User_ID is
      type ID_Type is (Number, Handle);
      type Object(T : ID_Type) is tagged record
         case T is
            when Number =>
               Number : Integer;
            when Handle =>
               Handle : Unbounded_String;
         end case;
      end record;
   end User_ID;
   
   -- User_IDのサブクラスなら何でも入るポインタ
   type User_ID_Ptr is access User_ID.Object'Class;

   package User_Handle is
      -- 制約はここで注入
      type Object is new User_ID.Object(T => User_ID.Handle) with null record;
   end User_Handle;

   package User_Number is
      -- 制約はここで注入
      type Object is new User_ID.Object(T => User_ID.Number) with null record;
   end User_Number;

   X : User_ID_Ptr;
   Y : User_ID_Ptr;

begin
   -- User_IDを使う場合(その場でHandleかNumberかを決められる)
   X := new User_ID.Object(T => User_ID.Number);
   X.Number := 1000;
   Y := new User_ID.Object(T => User_ID.Handle);
   Y.Handle := To_Unbounded_String("Foo");

   Put(X.Number); New_Line;
   Put(To_String(Y.Handle)); New_Line;
   --  1000
   -- Foo

   
   -- User_HandleとUser_Numberを使う場合
   X := new User_Handle.Object;
   X.Handle := To_Unbounded_String("Bar");
   Y := new User_Number.Object;
   Y.Number := 2000;

   Put(To_String(X.Handle)); New_Line;
   Put(Y.Number); New_Line;
   -- Bar
   --  2000
end Sample;

恐ろしくすっきりと書けますな。やはりAdaは最強ですね!

Comments

Name
YT
Datetime
2006-07-16T06:42:47+09:00
Message

例によっておじゃまします。私も知らなかったことも書かれておりためになります。

で、

>type Non_Negative_Integer renames Positive;

ですが、

subtype Non_Negative_Integer is Positive;(range限定無し)で同じ意味になるからじゃないでしょうか。

限定無しのsubtypeは全ての型に使えてるっぽいです。

それでは、(5)以降も期待しています。

Name
石川
Datetime
2006-07-16T16:40:12+09:00
Message

なるほど、subtypeで解決ですか。

ちょっと違和感ありますが、確かに同じ意味ですね。

Trackbacks

Trackback Ping URI

http://yudai.arielworks.com/memo/2006/07/15/141857.trackback

末尾に「7 + 3」の計算結果を繋げて下さい。例えば計算結果が「17」の場合、「141857.trackback17」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

Name (optional)
Email address or URI (optional)
Do the math below (required to filter comment spams)
7 + 3 + 8 =
Message (required)
Submit
連絡先、リンク、転載や複製などについては『サイト案内』をご覧ください。Powered by HIMMEL

I ♥ Validator