この間JavaやScala、Valaなど、サンプルコードをともなう投稿が増えてきたため、強調表示やWiki記法による軽量なマークアップなどいろいろ便利な感じのはてなダイアリーに移行することにしました。引きつづきValaその他について載せていきます。よろしく。
■m12i/d http://d.hatena.ne.jp/m12i/
2011年3月22日火曜日
2011年3月14日月曜日
WindowsでValaを動かす
きょうはちょっと小休止。「JavaプログラマーからみたVala」は置いておいて、公式サイトにあった別のメモの翻訳を載せます。
原典は、“Vala on Windows”(2011年3月14日取得)です。
******************************
WindowsでValaを動かす
Valaはいつもソースコードの形式でリリースされます。しかしValaコミュニティのメンバーが、Windows向けのバイナリを提供しています。.exeファイルとして提供されているインストーラにより、Windowsのための必要最低限のGNU環境(MinGW)──GlibやGTK+といったライブラリとともに、CコンパイラとValaコンパイラを提供します──をインストールできます。
インストールが終わると、次のようにしてValaプログラムをコンパイルできるようにります。
GTK+ライブラリを使用したアプリを起動した際に、コンソールウィンドウが表示されてしまう問題を抑制するためには、次の手順をとってください。
(最終更新: 2011年1月4日 13:04 /執筆: NicolasJoseph)
******************************
原典は、“Vala on Windows”(2011年3月14日取得)です。
******************************
WindowsでValaを動かす
Valaはいつもソースコードの形式でリリースされます。しかしValaコミュニティのメンバーが、Windows向けのバイナリを提供しています。.exeファイルとして提供されているインストーラにより、Windowsのための必要最低限のGNU環境(MinGW)──GlibやGTK+といったライブラリとともに、CコンパイラとValaコンパイラを提供します──をインストールできます。
インストールが終わると、次のようにしてValaプログラムをコンパイルできるようにります。
> valac hello.vala
GTK+ライブラリを使用したアプリを起動した際に、コンソールウィンドウが表示されてしまう問題を抑制するためには、次の手順をとってください。
- MinGW API for MS-Windowsをダウンロードします。“w32api-x.xx-mingw32-dev.tar.gz”という形式の名前が付いたファイルです。(訳者:“dev”という接尾辞のあるものです。)
- ダウンロードしたアーカイブファイルを、Vala(もしくはMinGW)がインストールされているディレクトリに展開します。(訳者:前述の.exeを使用してValaコンパイラ環境をインストールすると、Cディレクトリ直下に“vala-x.xx.x”というディレクトリが作成されます。このディレクトリには、libやincludeといったディレクトリが配置されています。MinGW API for MS-Windowsのアーカイブファイルを展開するとlibやincludeといったディレクトリがあらわれるので、これらをC:\vala-x.xx.x/libやC:\vala-x.xx.x/includeに上書きします。)
- Valaコンパイラを“-X –mwindows”というオプションとともに呼び出します(訳者: “-X –xxx”というのは“-xxx”の部分がCコンパイラに与えられるオプションであることをあらわしています)。
> valac -X -mwindows --pkg gtk+-2.0 hellogtk.vala
(最終更新: 2011年1月4日 13:04 /執筆: NicolasJoseph)
******************************
2011年3月13日日曜日
JavaプログラマーからみたVala (4) クラス②
最近なにかの拍子にVala言語に興味を持ってしまいました。Web上のドキュメントは限られているものの、Java言語との比較など平易なドキュメントもありましたので、学習をかねて稚拙な翻訳を載せていこうと思います。
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (4) クラス②
列挙型
Javaの場合: 列挙型はクラスをベースにしています。
Valaの場合: 列挙型は整数をベースにしています。メソッドは持てますが、コンストラクターやフィールドなどは持つことができません。
実行時の型判別
動的型チェック
Javaの場合: instanceof演算子を使用します。
Valaの場合: is演算子を使用します。
動的型キャスト
Javaの場合: Foo foo = (obj instanceof Foo) ? (Foo) obj : null
Valaの場合: Foo foo = obj as Foo
もちろん、 "(obj is Foo) ? (Foo) obj : null"も同様に有効な式です。
型情報を取得する
Javaの場合:
Valaの場合: typeof()を使用します。
オブジェクトの破棄
Javaの場合: 終了化子(finalizers)は、非決定論的です。
Valaの場合: デストラクタ(destructors)は、決定的です。
アノテーション
Javaの場合: アノテーションは自己定義的です。
Valaの場合: アノテーションの代わりに属性(attributes)を用います。属性はコンパイラに組み込まれています。書式は、“[AttributeName (param1 = value, param2 = value)]”というかたちです。バインディング(bindings)やD-Busインターフェースのためにしばしば使用さてます。バインディングのために使用されるいちばんよく見る属性は、“[CCode (...)]”です。
プロパティ
Javaの場合: Bean規約が用いられます。getX()やsetX()という形式のメソッドです。
Valaの場合: プロパティ──get {} ・ set {}ブロック──がサポートされており、フィールドのようにアクセスできます。
標準的な実装であれば、さらに短くできます。
デリゲート、クロージャ
Javaの場合: デリゲート・パターンの実装は、匿名内部クラスを使用することになります。
Valaの場合: Vala言語は、デリゲートとクロージャをサポートしています。
クロージャは外部スコープ(それ自身が定義されたスコープ)のローカル変数を束縛する無名のメソッドです(訳者:JavaScriptの関数がまさにそれです。Java6ではfinal宣言された変数でないと外部スコープの変数にはアクセスできませんが、JavaScriptも含め他の言語の中にはこうした変数の読み書きを行えるものがあります。JavaScriptではこの方法で他のコードがアクセスできない文字通り匿名の名前空間を展開・保持するテクニックが頻繁に使用されます)。クロージャはデリゲート型の変数に代入したり、デリゲート型の引数として他のメソッドに渡すことができます。
Java言語においては、匿名内部クラスにより、クロージャのまねごとができます。しかし匿名内部クラスが束縛できる外部スコープ・ローカル変数は、final宣言されたものだけです。一方、Vala言語ではクロージャはいかなる変数でも束縛できます。Java7ではクロージャのサポートが計画されています。メソッドは直接デリゲート変数に代入できます。
このことが示すのは、メソッドは(訳者:クロージャに限らずこれまで登場してきたあらゆる種類のメソッドは)オブジェクト同様に変数に格納したり引数として渡したりできるということです。
******************************
JavaプログラマーからみたVala (5)につづく──
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (4) クラス②
列挙型
Javaの場合: 列挙型はクラスをベースにしています。
Valaの場合: 列挙型は整数をベースにしています。メソッドは持てますが、コンストラクターやフィールドなどは持つことができません。
enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER;
public bool is_hot () {
return this == SUMMER;
}
}
実行時の型判別
動的型チェック
Javaの場合: instanceof演算子を使用します。
Valaの場合: is演算子を使用します。
動的型キャスト
Javaの場合: Foo foo = (obj instanceof Foo) ? (Foo) obj : null
Valaの場合: Foo foo = obj as Foo
もちろん、 "(obj is Foo) ? (Foo) obj : null"も同様に有効な式です。
型情報を取得する
Javaの場合:
Class c = Foo.class;
System.out.println(c.getName());
Foo = (Foo) c.newInstance();
Valaの場合: typeof()を使用します。
Type t = typeof (Foo);
stdout.printf ("%s\n", t.name ());
Foo o = (Foo) Object.new (t);
オブジェクトの破棄
Javaの場合: 終了化子(finalizers)は、非決定論的です。
public class Foo {
@Override
protected void finalize() {
}
}
Valaの場合: デストラクタ(destructors)は、決定的です。
public class Foo : Object {
~Foo () {
}
}
アノテーション
Javaの場合: アノテーションは自己定義的です。
Valaの場合: アノテーションの代わりに属性(attributes)を用います。属性はコンパイラに組み込まれています。書式は、“[AttributeName (param1 = value, param2 = value)]”というかたちです。バインディング(bindings)やD-Busインターフェースのためにしばしば使用さてます。バインディングのために使用されるいちばんよく見る属性は、“[CCode (...)]”です。
プロパティ
Javaの場合: Bean規約が用いられます。getX()やsetX()という形式のメソッドです。
public class Person {
private int age = 32;
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String[] args) {
Person p = new Person();
p.setAge(p.getAge() + 1);
}
}
Valaの場合: プロパティ──get {} ・ set {}ブロック──がサポートされており、フィールドのようにアクセスできます。
public class Person : Object {
private int _age = 32;
public int age {
get { return _age; }
set { _age = value; }
}
}
void main () {
var p = new Person ();
p.age++;
}
標準的な実装であれば、さらに短くできます。
public class Person : Object {
public int age { get; set; default = 32 }
}
デリゲート、クロージャ
Javaの場合: デリゲート・パターンの実装は、匿名内部クラスを使用することになります。
public interface MyDelegateType {
public void invoke(int a, double b);
}
public class Demo {
private static void foo(MyDelegateType deleg) {
deleg.invoke(32, 0.25);
}
public static void main(String[] args) {
MyDelegateType deleg = new MyDelegateType () {
public void invoke(int a, double b) {
System.out.println("a = " + a + "; b = " + b);
}
};
deleg.invoke(42, 0.75);
foo(deleg);
}
}
Valaの場合: Vala言語は、デリゲートとクロージャをサポートしています。
delegate void MyDelegateType (int a, double b);
void foo (MyDelegateType deleg) {
deleg (32, 0.25); // invoke delegate
}
void main () {
MyDelegateType deleg = (a, b) => {
stdout.printf ("a = %d; b = %g\n", a, b);
};
deleg (42, 0.75); // invoke delegate
foo (deleg); // pass delegate to a method
}
クロージャは外部スコープ(それ自身が定義されたスコープ)のローカル変数を束縛する無名のメソッドです(訳者:JavaScriptの関数がまさにそれです。Java6ではfinal宣言された変数でないと外部スコープの変数にはアクセスできませんが、JavaScriptも含め他の言語の中にはこうした変数の読み書きを行えるものがあります。JavaScriptではこの方法で他のコードがアクセスできない文字通り匿名の名前空間を展開・保持するテクニックが頻繁に使用されます)。クロージャはデリゲート型の変数に代入したり、デリゲート型の引数として他のメソッドに渡すことができます。
Java言語においては、匿名内部クラスにより、クロージャのまねごとができます。しかし匿名内部クラスが束縛できる外部スコープ・ローカル変数は、final宣言されたものだけです。一方、Vala言語ではクロージャはいかなる変数でも束縛できます。Java7ではクロージャのサポートが計画されています。メソッドは直接デリゲート変数に代入できます。
delegate int MyDelegateType (int a, double b);
int add (int a, int b) {
return a + b;
}
int sub (int a, int b) {
return a - b;
}
void main () {
MyDelegateType deleg = add;
int sum = deleg (2, 3);
deleg = sub;
int diff = deleg (8, 4);
}
このことが示すのは、メソッドは(訳者:クロージャに限らずこれまで登場してきたあらゆる種類のメソッドは)オブジェクト同様に変数に格納したり引数として渡したりできるということです。
******************************
JavaプログラマーからみたVala (5)につづく──
JavaプログラマーからみたVala (3) クラス
最近なにかの拍子にVala言語に興味を持ってしまいました。Web上のドキュメントは限られているものの、Java言語との比較など平易なドキュメントもありましたので、学習をかねて稚拙な翻訳を載せていこうと思います。
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (3) クラス
継承
Javaの場合: extendsとimplementsを使用します。
Valaの場合: コロンとそれに続くカンマ区切りリストであらわします。このリストには親クラスもインターフェースもともに含まれます。
Vala言語では親クラス(super)を基本クラス(base)と呼びます。
オブジェクトベースクラス
Javaの場合: すべてのクラスはObject(java.lang.Object)から暗黙的に継承します。
Valaの場合: Object(Glib.Object)からの暗黙的な継承は行われません。
Glib.Objectからの継承を行わないとどうなるのでしょうか? このような場合、そのクラスは若干軽量になる一方、プロパティ変更通知(property change notifications)などのいくつかの機能を欠いたものになります。そしてこのクラスは共通基本クラスを持たないことになります。たいていの場合、Glib.Objectからの継承は必要となるでしょう。
メソッド多重定義
Javaの場合: 以下の例のようにメソッドの多重定義(overloading)が行えます。
Valaの場合: メソッドの多重定義はできません。別名を付けるか、引数にデフォルト値を指定することで代わりとします。
Vala言語がメソッド多重定義の機能をサポートしないのは、Valaのライブラリが、C言語コードからアクセス可能であるよう意図して記述されているからです(意訳)。
コンストラクタ多重定義
Javaの場合: コンストラクタの多重定義ができます。
Valaの場合: 多重定義ではなく、名前付きコンストラクタ(named constructors)を使用します。
コンストラクタ連鎖
Javaの場合: “this()”記法で実現します。
Valaの場合: “this()”記法もしくは“this.コンストラクタ名 ()”記法で実現します。
オーバーライド
Javaの場合: すべてのメソッドはデフォルトで仮想メソッド(C#で導入された概念。オーバーライド可能なメソッド)です。オーバーライドを阻止するにはfinal修飾子を使用します。
Valaの場合: すべてのメソッドは、デフォルトで非仮想メソッド(オーバーライド不可能なメソッド)です。オーバーライドを可能にするには明示的にvirtual修飾子を使用する必要があります。 他方、Vala言語には@Overrideアノテーションの代わりにoverride修飾子があり、この修飾子の使用は任意ではありません(強制です)。
アクセス修飾子
クラスメンバーのアクセスはデフォルトでprivateですが、publicアクセスのメンバーと対称的にさせるために、明示的にprivate修飾子を使用することもできます。
インターフェース
Javaの場合: インターフェースのメソッドは暗黙のうちに抽象メソッドです。
Valaの場合: abstract修飾子は明示的に使用する必要があります。
なぜでしょう? それはVala言語におけるインターフェースが非抽象メソッド(実装をともなうメソッド)をメンバーとすることができるからです。つまりVala言語のインターフェースは、いわゆるミックスイン(mixins。限定的な多重継承)を実現するために利用できるのです。
Vala言語におけるインターフェースは、──例えばファクトリーメソッドのような──staticメソッドを持つこともできます。
Javaの場合: インターフェースは継承可能です。
Valaの場合: インターフェースは必要条件として働きます。
Valaでは、インターフェースは他のインターフェースから継承できません。しかし他のインターフェースを必要条件として宣言できます。これによりおおよそ同じことを実現できます。インターフェースは、インターフェースだけでなくクラスも前提条件として宣言することができます。これにより、あるインターフェース(を継承したあるクラス)のインスタンスが、Glib.Objectのサブクラスでもあることを保証することができます。この事実──インターフェースは他のインターフェースのメンバーを継承できない──は、ほとんど技術的なちがいでしかありません。実際のところVala言語のインターフェースのシステムは、Javaにおけるそれと同じように働きます。ただ、Valaにおいてはクラス継承を必要条件とするという機能もある、ということです。
******************************
JavaプログラマーからみたVala (4)につづく──
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (3) クラス
継承
Javaの場合: extendsとimplementsを使用します。
public class Demo extends Foo implements Bar {
public Demo() {
super();
}
}
Valaの場合: コロンとそれに続くカンマ区切りリストであらわします。このリストには親クラスもインターフェースもともに含まれます。
public class Demo : Foo, Bar {
public Demo () {
base ();
}
}
Vala言語では親クラス(super)を基本クラス(base)と呼びます。
オブジェクトベースクラス
Javaの場合: すべてのクラスはObject(java.lang.Object)から暗黙的に継承します。
public class Foo {
// ...
}
Valaの場合: Object(Glib.Object)からの暗黙的な継承は行われません。
public class Foo : Object {
// ...
}
Glib.Objectからの継承を行わないとどうなるのでしょうか? このような場合、そのクラスは若干軽量になる一方、プロパティ変更通知(property change notifications)などのいくつかの機能を欠いたものになります。そしてこのクラスは共通基本クラスを持たないことになります。たいていの場合、Glib.Objectからの継承は必要となるでしょう。
メソッド多重定義
Javaの場合: 以下の例のようにメソッドの多重定義(overloading)が行えます。
public class Demo {
public void draw(String text) { }
public void draw(Shape shape) { }
/* メソッドのオーバーロード、
そしてより引数の数の少ないメソッドによる、
引数の数の多いそれの利用*/
void f(int x, String s, double z) { }
void f(int x, String s) {
f(x, s, 0.5);
}
void f(int x) {
f(x, "hello");
}
}
Valaの場合: メソッドの多重定義はできません。別名を付けるか、引数にデフォルト値を指定することで代わりとします。
public class Demo : Object {
public void draw_text (string text) {
}
public void draw_shape (Shape shape) {
}
/* 引数にデフォルト値が指定されたメソッド */
void f (int x, string s = "hello", double z = 0.5) {
}
}
Vala言語がメソッド多重定義の機能をサポートしないのは、Valaのライブラリが、C言語コードからアクセス可能であるよう意図して記述されているからです(意訳)。
コンストラクタ多重定義
Javaの場合: コンストラクタの多重定義ができます。
public class Foo {
public Foo() { }
public Foo(int foo) { }
public Foo(String bar) { }
}
new Foo();
new Foo(42);
new Foo("hello");
Valaの場合: 多重定義ではなく、名前付きコンストラクタ(named constructors)を使用します。
public class Foo : Object {
public Foo () { }
public Foo.with_foo (int foo) { }
public Foo.from_bar (string bar) { }
}
new Foo ();
new Foo.with_foo (42);
new Foo.from_bar ("hello");
コンストラクタ連鎖
Javaの場合: “this()”記法で実現します。
class Foo {
public Foo() {
this("bar");
}
public Foo(string bar) {
}
}
Valaの場合: “this()”記法もしくは“this.コンストラクタ名 ()”記法で実現します。
class Foo : Object {
public Foo () {
this.with_bar ("bar");
}
public Foo.with_bar (string bar) {
}
}
オーバーライド
Javaの場合: すべてのメソッドはデフォルトで仮想メソッド(C#で導入された概念。オーバーライド可能なメソッド)です。オーバーライドを阻止するにはfinal修飾子を使用します。
public class Super {
public int myMethod(int x, int y) { }
public final void anotherMethod() { }
}
public class Sub extends Super {
@Override
public int myMethod(int x, int y) {
super.myMethod(x, y);
// ...
}
}
Valaの場合: すべてのメソッドは、デフォルトで非仮想メソッド(オーバーライド不可能なメソッド)です。オーバーライドを可能にするには明示的にvirtual修飾子を使用する必要があります。 他方、Vala言語には@Overrideアノテーションの代わりにoverride修飾子があり、この修飾子の使用は任意ではありません(強制です)。
public class Super : Object {
public virtual int my_method (int x, int y) { }
public void another_method () { }
}
public class Sub : Super {
public override int my_method (int x, int y) {
base.my_method (x, y);
// ...
}
}
アクセス修飾子
Java | Vala |
public | public |
protected | protected |
package-private (デフォルト) | internal |
private | private (デフォルト) |
クラスメンバーのアクセスはデフォルトでprivateですが、publicアクセスのメンバーと対称的にさせるために、明示的にprivate修飾子を使用することもできます。
インターフェース
Javaの場合: インターフェースのメソッドは暗黙のうちに抽象メソッドです。
public interface Foo {
public void foo(int i);
public int bar(String s, double d);
}
Valaの場合: abstract修飾子は明示的に使用する必要があります。
public interface Foo {
public abstract void foo (int i);
public abstract int bar (string s, double d);
}
なぜでしょう? それはVala言語におけるインターフェースが非抽象メソッド(実装をともなうメソッド)をメンバーとすることができるからです。つまりVala言語のインターフェースは、いわゆるミックスイン(mixins。限定的な多重継承)を実現するために利用できるのです。
Vala言語におけるインターフェースは、──例えばファクトリーメソッドのような──staticメソッドを持つこともできます。
Javaの場合: インターフェースは継承可能です。
public interface IfaceA {
public void methodA();
}
public interface IfaceB extends IfaceA {
public void methodB();
}
public class Demo implements IfaceB {
public void methodA() { }
public void methodB() { }
}
Valaの場合: インターフェースは必要条件として働きます。
interface IfaceA : Object {
public abstract void method_a ();
}
interface IfaceB : Object, IfaceA {
public abstract void method_b ();
}
class Demo : Object, IfaceA, IfaceB {
public void method_a () { }
public void method_b () { }
}
Valaでは、インターフェースは他のインターフェースから継承できません。しかし他のインターフェースを必要条件として宣言できます。これによりおおよそ同じことを実現できます。インターフェースは、インターフェースだけでなくクラスも前提条件として宣言することができます。これにより、あるインターフェース(を継承したあるクラス)のインスタンスが、Glib.Objectのサブクラスでもあることを保証することができます。この事実──インターフェースは他のインターフェースのメンバーを継承できない──は、ほとんど技術的なちがいでしかありません。実際のところVala言語のインターフェースのシステムは、Javaにおけるそれと同じように働きます。ただ、Valaにおいてはクラス継承を必要条件とするという機能もある、ということです。
******************************
JavaプログラマーからみたVala (4)につづく──
JavaプログラマーからみたVala (2) 型
最近なにかの拍子にVala言語に興味を持ってしまいました。Web上のドキュメントは限られているものの、Java言語との比較など平易なドキュメントもありましたので、学習をかねて稚拙な翻訳を載せていこうと思います。
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVava(2)
基本型
Vala言語では基本型もメソッドを持ちます。例えば以下のように──
文字列型
Javaの場合:
型名は、Stringです。
意味的等価性をチェックするにはequals(String)メソッドを使用します。
Valaの場合:
型名はstringです。(小文字です。)
意味的等価性をチェックするには==演算子を使用します。
Valaでは文字列の(==演算子による)比較は、内容ベースで行われます。参照ベースではありません。<、>、<=、>=などの比較演算子は、文字列の辞書的比較に使用できます。文字列はswitch文で使用できます。
Vala文字列はUTF-8で保持されます。
Vala言語における文字列のその他の特徴
Vala言語は逐語的文字列リテラル(verbatim strings)をサポートしています。逐語的文字列リテラルは、3連ダブルクオテーションで囲います("""...""")。
Vala言語は文字列テンプレートをサポートしています。@"..."で囲われた文字列は、$記号を接頭辞にした式をその内容に含むことができます。
配列
動的な成長
Vala言語では、配列に対して+=演算子を用いて、動的に要素を追加していくことができます。配列は2のべき乗のサイズで(動的に)メモリー上に再配置されます。
境界はチェックしない
Vala言語では、いかなる場合にも、実行環境により配列の境界がチェックされることはありません。
多次元の配列
Javaの場合: ジャグ配列を使用できます。([][]。配列の配列です。)
Valaの場合: 長方形配列を使用できます。(rectangular multi-dimensional arrays。 [,]、 [,,]。Javaにおける多次元配列は配列オブジェクトに対する参照を要素とする配列ですが、Valaにおけるそれは多次元配列そのものが1つの連続したメモリーブロックに配置されます。)Valaでも、ジャグ配列のサポートが予定されています。
型推論
Vala言語では、ローカル変数に関して、型推論(暗黙型決定)と呼ばれるメカニズムが適用されます。このメカニズムの下では、──変数の初期化の際の式からコンパイラが型を推論できる場合──ローカル変数は型名ではなくvarキーワードによって宣言できます。これにより、不要な冗長性(意訳:ソースコードの可読性に対してメリットにならない冗長性)が取り除かれ、ジェネリック型の使用が簡単になります。例えば以下のように──
これに対して型推論メカニズムがないと以下のようになります──
もちろん、すべての変数は静的型システムの管理下にあります(Still, everything is statically typed。意訳:動的型システムとはちがいます)。
foreach文
Javaの場合: for (int i : numbers) { }
Valaの場合: foreach (int i in numbers) { }
******************************
JavaプログラマーからみたVala (3)につづく──
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVava(2)
基本型
- 標準的な型(intやlongなど)のサイズはアーキテクチャに依存します。こうした型のサイズを求めるには、sizeof()を使用します。例えば、sizeof(int)といった具合です。
- Valaで追加された型──int8、int16、int32、int64(すべて符号あり)、uint8、uint16、uint32、uint64(すべて符号なし)は、アーキテクチャ非依存であることが保証されています。
- byte型はありません。(代わりにuint8を使用しましょう。)
- Javaにおけるboolean型は、Valaではbool型です。
- Valaで追加された基本型には、unichar型があります。これはユニコード文字をあらわします。
Vala言語では基本型もメソッドを持ちます。例えば以下のように──
int a = -4.abs ();
string s = a.to_string ();
int b = int.max (5, 7); // int型の静的メソッドが呼ばれています。
文字列型
Javaの場合:
型名は、Stringです。
意味的等価性をチェックするにはequals(String)メソッドを使用します。
Valaの場合:
型名はstringです。(小文字です。)
意味的等価性をチェックするには==演算子を使用します。
Valaでは文字列の(==演算子による)比較は、内容ベースで行われます。参照ベースではありません。<、>、<=、>=などの比較演算子は、文字列の辞書的比較に使用できます。文字列はswitch文で使用できます。
Vala文字列はUTF-8で保持されます。
Vala言語における文字列のその他の特徴
Vala言語は逐語的文字列リテラル(verbatim strings)をサポートしています。逐語的文字列リテラルは、3連ダブルクオテーションで囲います("""...""")。
string verbatim = """Verbatim strings don't evaluate escape sequences
like \n, \t, ... and may span multiple lines. The line breaks are part
of the string. You can use quotation marks (") and backslashes (\)
inside a verbatim string without escaping them."""
Vala言語は文字列テンプレートをサポートしています。@"..."で囲われた文字列は、$記号を接頭辞にした式をその内容に含むことができます。
string name = "John";
stdout.printf (@"Welcome, $name!");
stdout.printf (@"3 + 2 = $(3 + 2)");
配列
動的な成長
Vala言語では、配列に対して+=演算子を用いて、動的に要素を追加していくことができます。配列は2のべき乗のサイズで(動的に)メモリー上に再配置されます。
int[] squares = {};
for (int i = 0; i < 100; i++) {
squares += i * i;
}
境界はチェックしない
Vala言語では、いかなる場合にも、実行環境により配列の境界がチェックされることはありません。
int[] a = new int[10];(Valaの将来のバージョンでは、任意の境界チェック機能を実装することが検討されています。)
a[20] = 1; // 危険なコード!
多次元の配列
Javaの場合: ジャグ配列を使用できます。([][]。配列の配列です。)
int[][] matrix = new int[3][];
for (int[] row : matrix) {
row = new int[4];
}
Valaの場合: 長方形配列を使用できます。(rectangular multi-dimensional arrays。 [,]、 [,,]。Javaにおける多次元配列は配列オブジェクトに対する参照を要素とする配列ですが、Valaにおけるそれは多次元配列そのものが1つの連続したメモリーブロックに配置されます。)Valaでも、ジャグ配列のサポートが予定されています。
int[,] matrix = new int[3,4];
型推論
Vala言語では、ローカル変数に関して、型推論(暗黙型決定)と呼ばれるメカニズムが適用されます。このメカニズムの下では、──変数の初期化の際の式からコンパイラが型を推論できる場合──ローカル変数は型名ではなくvarキーワードによって宣言できます。これにより、不要な冗長性(意訳:ソースコードの可読性に対してメリットにならない冗長性)が取り除かれ、ジェネリック型の使用が簡単になります。例えば以下のように──
var obj = new Object ();
var map = new HashMap<string, int>();
var str = "hello, world";
var arr = new int[10];
これに対して型推論メカニズムがないと以下のようになります──
Object obj = new Object ();
HashMap<string, int>map = new HashMap<string, int> ();
string str = "hello, world";
int[] arr = new int[10];
もちろん、すべての変数は静的型システムの管理下にあります(Still, everything is statically typed。意訳:動的型システムとはちがいます)。
foreach文
Javaの場合: for (int i : numbers) { }
Valaの場合: foreach (int i in numbers) { }
******************************
JavaプログラマーからみたVala (3)につづく──
JavaプログラマーからみたVala (1) ソースコード
最近なにかの拍子にVala言語に興味を持ってしまいました。Web上のドキュメントは限られているものの、Java言語との比較など平易なドキュメントもありましたので、学習をかねて稚拙な翻訳を載せていこうと思います。
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (1)
ソースファイル
Javaの場合: *.java
Valaの場合: *.vala
コンパイル
Javaの場合: JVMバイトコード(.classファイル)にコンパイルされます。
ライブラリの使用
Javaの場合: .jarファイルを指定します。
Javaの場合:
ソースコードの組織化
ソースコード・ファイルについて
Javaの場合: 1つのファイルにつき、トップレベルのクラス(toplevel class。内部クラスでなく、パブリックなもの)は1つだけです。ファイル名はクラス名と一致します。
Valaの場合: 1つのファイルには複数のクラスを記述できます。ファイル名はクラス名と一致している必要はありません。
ヒエラルキーについて
Javaの場合: パッケージ概念があります。パッケージはディレクトリ構造によりあらわされます。またドメイン名を反転させた書式で構造化されます。
デフォルトで読み込まれる名前空間について
Javaの場合: java.langパッケージ配下のクラスがデフォルトで読み込まれています。
Valaの場合: Glib名前空間がデフォルトで読み込まれています。
エントリーポイント
Javaの場合: public static void main(String[] args)
Valaの場合: static int main (string[] args)
mainメソッドは、クラス外部で定義されても、privateアクセス修飾子が添えられていても、あるいは終了コード(exit code)としてintを返してもよいのです。その上argsはオプションです。
******************************
JavaプログラマーからみたVala (2)につづく──
原典は、“Vala for Java Programmers”(2011年3月13日取得)です。
******************************
JavaプログラマーからみたVala (1)
ソースファイル
Javaの場合: *.java
Valaの場合: *.vala
コンパイル
Javaの場合: JVMバイトコード(.classファイル)にコンパイルされます。
$ javac SourceFile1.java SourceFile2.javaValaの場合: C言語ソースコードに翻訳されたのち、ネイティブコードにコンパイルされます。
$ valac source1.vala source2.vala -o programVala言語における標準オブジェクトシステムはGOjectであり、コンパイルされたValaライブラリは、有効なC言語ライブラリとなります。
ライブラリの使用
Javaの場合: .jarファイルを指定します。
$ javac -classpath foo-1.0.jar;bar-3.0.jar SourceFile.javaValaの場合: パッケージを指定します(.vapiファイルを介してCライブラリにアクセスします)
$ valac --pkg foo-1.0 --pkg bar-3.0 source.vala
Javaの場合:
- クラス、インターフェース、列挙型: キャメルケース(パスカルケース)。
- メソッド、ローカル変数、フィールド: ローワーキャメルケース。
- 定数、列挙型インスタンス(enum values): アッパーケース(アンダーバーで結合)。
- クラス、インターフェース、構造体、列挙型、デリゲート型、名前空間: キャメルケース(パスカルケース)。
- メソッド、ローカル変数、フィールド、プロパティ、シグナル: ローワーケース(アンダーバーで結合)。
- 定数、列挙型インスタンス: アッパーケース(アンダーバーで結合)。
ソースコードの組織化
ソースコード・ファイルについて
Javaの場合: 1つのファイルにつき、トップレベルのクラス(toplevel class。内部クラスでなく、パブリックなもの)は1つだけです。ファイル名はクラス名と一致します。
Valaの場合: 1つのファイルには複数のクラスを記述できます。ファイル名はクラス名と一致している必要はありません。
ヒエラルキーについて
Javaの場合: パッケージ概念があります。パッケージはディレクトリ構造によりあらわされます。またドメイン名を反転させた書式で構造化されます。
import javax.swing.*;Valaの場合: 名前空間(namespaces)があります。ディレクトリ構造とは関係ありません。反転ドメイン名書式もとりません。
package org.foo.bar;
// ...
using Gtk;Valaの名前空間内には、所属クラスのないメソッドも存在します。これらは暗黙の静的メンバー(implicitly static)です。
namespace Foo.Bar {
// ...
}
デフォルトで読み込まれる名前空間について
Javaの場合: java.langパッケージ配下のクラスがデフォルトで読み込まれています。
Valaの場合: Glib名前空間がデフォルトで読み込まれています。
エントリーポイント
Javaの場合: public static void main(String[] args)
Valaの場合: static int main (string[] args)
mainメソッドは、クラス外部で定義されても、privateアクセス修飾子が添えられていても、あるいは終了コード(exit code)としてintを返してもよいのです。その上argsはオプションです。
******************************
JavaプログラマーからみたVala (2)につづく──
2011年1月9日日曜日
ブクログで探しちゃうブックマークレット
ブクログで配布されていた「ブクログに追加」ブックマークレットが、岩波書店のページとかその他でぜんぜん役に立たないことにイラっときてつくりました。
「ISBN : ~」とか「IEBN-10 : ~」とか「IEBN-13 : ~」とかの記述をページ内で探して、その情報をもとにブクログで書籍検索を実施します。そんだけです。
以下のリンクをブックマークバーなどにドラッグすれば、使えるようになるはずです。
ISBNをもとにブクログで探す
ISBNをもとにブクログで探す(ASIN・EAN対応)
※テスト用ISBN-13: 978-4791762460
「ISBN : ~」とか「IEBN-10 : ~」とか「IEBN-13 : ~」とかの記述をページ内で探して、その情報をもとにブクログで書籍検索を実施します。そんだけです。
以下のリンクをブックマークバーなどにドラッグすれば、使えるようになるはずです。
ISBNをもとにブクログで探す
ISBNをもとにブクログで探す(ASIN・EAN対応)
※テスト用ISBN-13: 978-4791762460
AppWidgetの作り方
AppWidget(以下、ウィジェット)は、Androidアプリに組み込まれる形で配布され、ユーザーが自身の端末のホームスクリーン上に自由に配置できる小さなアプリです。
ウィジェットの定義ファイルのなかで、更新間隔を指定しておくことで、一定の時間間隔で表示をアップデートしていくことが可能です。表示の更新のタイミングが限られているため、「常駐アプリ」とはかならずしも分類できませんが、画面=Activityを持つAndroidアプリ本体の、高機能なランチャー程度には活用できます。
※より正確に言えば、ウィジェットとは、ユーザーがウィジェットを作成したときや、あらかじめ定められた時間間隔が経過したときに、Androidプラットフォームのシステム側からメッセージを受け取るブロードキャスト・レシーバー(AppWidgetプロバイダー)により初期化・更新されるView、です。
Androidアプリにウィジェットを組み込むには、以下のファイルが必要になります。
①AppWidgetProviderInfo (XML)
ウィジェットのメタデータを記述するもので、ウィジェットの表示を構成するためのレイアウト・リソース、表示更新の頻度、AppWidgetプロバイダー(後述)のクラス名を、XMLで記述します。
②AppWidgetProvider (Class)
ウィジェットの初期化などで呼び出される処理を実装するAppWidgetプロバイダー(ブロードキャスト・レシーバーの一種)の実装クラスです。
③レイアウト (XML)
ウィジェットの表示に使用されるレイアウト・リソースです。サイズの指定方法が独特?です。
④AndroidManifest(XML)
言わずと知れたAndroidアプリのメタデータやコンポーネントについての記述をするためのXMLです。AppWidgetProviderがブロードキャスト・レシーバーの一種であることから、記述の追加が必要になります。
以下では、Android Developpersのリファレンスのコードを参考に説明を行います。
1. AndroidManifestへの登録
Intentフィルターの部分と、AppWidgetプロバイダーのメタデータについて記述したXMLの在所を示す部分が重要です。
2. AppWidgetプロバイダーのメタデータの記述
AndroidManifestで示した場所に、プロバイダーのメタデータを記述したXMLを配置します。
ウィジェットのサイズ指定の単位となるのは、Android端末のホームスクリーンをタテヨコ4分割した「セル」の幅/高さであり、Android Developpersでは、「
updatePeriodMillis属性では、ウィジェット の更新間隔を指定します。単位はミリ秒となります。
更新は最短で30分以上の間隔を置いて実行されます。この属性に0を指定すると、更新は行われなくなり、後述のAppWidgetプロバイダーのonUpdateメソッドは、ウィジェット作成時にしか呼ばれなくなります。
configure属性は、ウィジェットにセッティング用画面がある場合のものです。ウィジェットが作成された際にここで指定したActivityが実行され、ウィジェットのプロパティを初期化すること出来るようです。(詳しくはこちらを参照。)
3. ウィジェットのレイアウトを作成
ウィジェットのレイアウトで使用できるViewGroupとViewには制限があるようです。
ViewGroupについては、FrameLayout、LinearLayout、RelativeLayout。
Viewについては、AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextViewです。
ButtonやImageViewなどのほかに、AnalogClockなどが挙げられているのがおもしろいところです。
4. AppWidgetプロバイダーを実装
AppWidgetProviderクラスの中で、一番重要なのは、onUpdateメソッドでしょう。
このメソッドは、プロバイダーのメタデータの記述(XML)の中で指定した更新タイミングに呼び出されます。
また、より重要なこととして、 ユーザーによりウィジェットが画面に追加された際にも、このメソッドが呼び出されます。したがって、このメソッドの中でウィジェットの表示の初期化や、必要なサービスの起動などを実行することになります。
しかもです。このメソッドの第3引数は、AppWidgetインスタンスのID配列です。この点について、Android Developpersの説明では、大意以下のように述べています。
したがって、ウィジェットのボタンをクリックしたときに、アプリケーション本体となるActivityを起動する、といったことをする場合、以下のようなコードを記述すればよいことになります。
その他のメソッドとしては、onEnabled、onDisabled、onReceiveがあります。これらがonUpdateメソッド同様、あくまでもプロバイダーの生成~破棄までのライフサイクルに関わってくるものであり、AppWidgetの個別のインスタンスに関連するものではない、ということに注意してください。
これらのメソッドの解説は、Android DeveloppersのAPIリファレンスにあります。
ウィジェットの定義ファイルのなかで、更新間隔を指定しておくことで、一定の時間間隔で表示をアップデートしていくことが可能です。表示の更新のタイミングが限られているため、「常駐アプリ」とはかならずしも分類できませんが、画面=Activityを持つAndroidアプリ本体の、高機能なランチャー程度には活用できます。
※より正確に言えば、ウィジェットとは、ユーザーがウィジェットを作成したときや、あらかじめ定められた時間間隔が経過したときに、Androidプラットフォームのシステム側からメッセージを受け取るブロードキャスト・レシーバー(AppWidgetプロバイダー)により初期化・更新されるView、です。
Androidアプリにウィジェットを組み込むには、以下のファイルが必要になります。
①AppWidgetProviderInfo (XML)
ウィジェットのメタデータを記述するもので、ウィジェットの表示を構成するためのレイアウト・リソース、表示更新の頻度、AppWidgetプロバイダー(後述)のクラス名を、XMLで記述します。
②AppWidgetProvider (Class)
ウィジェットの初期化などで呼び出される処理を実装するAppWidgetプロバイダー(ブロードキャスト・レシーバーの一種)の実装クラスです。
③レイアウト (XML)
ウィジェットの表示に使用されるレイアウト・リソースです。サイズの指定方法が独特?です。
④AndroidManifest(XML)
言わずと知れたAndroidアプリのメタデータやコンポーネントについての記述をするためのXMLです。AppWidgetProviderがブロードキャスト・レシーバーの一種であることから、記述の追加が必要になります。
以下では、Android Developpersのリファレンスのコードを参考に説明を行います。
1. AndroidManifestへの登録
Intentフィルターの部分と、AppWidgetプロバイダーのメタデータについて記述したXMLの在所を示す部分が重要です。
<receiver android:name="ExampleAppWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
2. AppWidgetプロバイダーのメタデータの記述
AndroidManifestで示した場所に、プロバイダーのメタデータを記述したXMLを配置します。
ウィジェットのサイズ指定の単位となるのは、Android端末のホームスクリーンをタテヨコ4分割した「セル」の幅/高さであり、Android Developpersでは、「
(セル数 * 74) - 2」という数式が紹介されています。
この数値を、dp(画面密度非依存ピクセル)で
minWidthとminHeight属性に指定することで、ウィジェットのサイズを指定します。ウィジェットは、ユーザーによりサイズ変更可能です。updatePeriodMillis属性では、ウィジェット の更新間隔を指定します。単位はミリ秒となります。
更新は最短で30分以上の間隔を置いて実行されます。この属性に0を指定すると、更新は行われなくなり、後述のAppWidgetプロバイダーのonUpdateメソッドは、ウィジェット作成時にしか呼ばれなくなります。
configure属性は、ウィジェットにセッティング用画面がある場合のものです。ウィジェットが作成された際にここで指定したActivityが実行され、ウィジェットのプロパティを初期化すること出来るようです。(詳しくはこちらを参照。)
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/example_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigure">
</appwidget-provider>
3. ウィジェットのレイアウトを作成
ウィジェットのレイアウトで使用できるViewGroupとViewには制限があるようです。
ViewGroupについては、FrameLayout、LinearLayout、RelativeLayout。
Viewについては、AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextViewです。
ButtonやImageViewなどのほかに、AnalogClockなどが挙げられているのがおもしろいところです。
4. AppWidgetプロバイダーを実装
AppWidgetProviderクラスの中で、一番重要なのは、onUpdateメソッドでしょう。
このメソッドは、プロバイダーのメタデータの記述(XML)の中で指定した更新タイミングに呼び出されます。
また、より重要なこととして、 ユーザーによりウィジェットが画面に追加された際にも、このメソッドが呼び出されます。したがって、このメソッドの中でウィジェットの表示の初期化や、必要なサービスの起動などを実行することになります。
しかもです。このメソッドの第3引数は、AppWidgetインスタンスのID配列です。この点について、Android Developpersの説明では、大意以下のように述べています。
ユーザーは同じAppWidgetのインスタンスをいくつも作成することができる。例えば、あるAppWidgetが、2時間ごとに更新されるよう指定されていたとする。まず1つめのAppWidgetインスタンスがホームスクリーン上に作成され、その1時間後、もう1つのAppWidgetインスタンスが作成される。1つめのAppWidgetがスクリーン上に追加されてから2時間後、onUpdateメソッドが呼ばれる。しかしその1時間後(2つ目のインスタンスが作成されてから2時間後)にonUpdateが呼ばれることはない。更新のスケジューリングは、あくまでも1つめのAppWidgetインスタンスの生成を基準に行われる。つまり、ここでupdatePeriodMillis属性があくまでもプロバイダーの属性であり、ウィジェットの属性ではなかったことがここで思い出されるわけですが、いずれにしてもこのメソッドはホームスクリーン上のすべてのウィジェットについて、その更新/初期化を一時に実施するものであるということです。
したがって、ウィジェットのボタンをクリックしたときに、アプリケーション本体となるActivityを起動する、といったことをする場合、以下のようなコードを記述すればよいことになります。
public class ExampleAppWidgetProvider extends AppWidgetProvider {onUpdateメソッドに対応するものとしては、onDeletedがあります。
public void onUpdate(Context context,
AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
// このプロバイダーに所属するAppWidgetのそれぞれについて処理を行う
for (int i=0; i
int appWidgetId = appWidgetIds[i];
// ExampleActivityを起動するIntentを生成
Intent intent = new Intent(context, ExampleActivity.class);
// それをPendingIntentに変換する
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// AppWidgetのレイアウト・リソースを取得
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.appwidget_provider_layout);
// 第1引数にClickリスナーを設定したいViewのID、
// 第2引数にClickされた際に発行されるPendingIntentを指定
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// IDで指定したAppWidgetの表示を、先ほど取得し、リスナーをセットした
// RemoteViewsで更新する/初期化するようAppWidgetManagerに指示
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
onDeleted(Context context, int[] appWidgetIds)
その他のメソッドとしては、onEnabled、onDisabled、onReceiveがあります。これらがonUpdateメソッド同様、あくまでもプロバイダーの生成~破棄までのライフサイクルに関わってくるものであり、AppWidgetの個別のインスタンスに関連するものではない、ということに注意してください。
これらのメソッドの解説は、Android DeveloppersのAPIリファレンスにあります。
登録:
投稿 (Atom)