それAdaならできるよ
それ、Adaならできるよ
Adaなら83の時代から部分集合余裕だぜー。ていうか、JavaってなんでJ2SE5まで列挙型なかったんだろね。気持ちは何となく分かるけども。
Ascii_String
はString
型がまんまだし、Non_Negative_Integer
もやっぱりPositive
型が最初からInteger
のsubtype
として定義されているのでそれを使えばよし。
Scoreはこんな感じかな。派生型を使ってInteger
との演算を禁止してるけど、状況によってはやり過ぎかも。どうせならScore_n
も派生型にして、100と1000の間での演算を禁止してもいいかな。めんどくさい場合はInteger
のsubtype
にしちゃえば、型変換が不要なので楽ちん。
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は最強ですね!