2018年4月22日日曜日

2: UNO、そのエッセンスとLibreOfficeまたはOpenOfficeとの関係

<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>

UNOは、LibreOfficeまたはOpenOfficeにとって、単なる周辺インターフェイスではありません。そのエッセンスおよび影響の貧しい理解があなたの足かせになっているかもしれません。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice

この記事の目次


開始コンテキスト


  • 読者は、コンピューターについての基本的な知識(プログラム、プロセスなどが何か)を持っている。
  • 読者は、プログラミングについての基本的な知識(ランタイム環境、ライブラリ、プリミティブデータ型、複合データ型などが何か)を持っている。
  • 読者は、オブジェクト指向プログラミングパラダイムについての基本的な知識(特に、'オブジェクト'、'クラス'、'インターフェイス'、'実装'の概念)を持っている。
  • 読者は、JavaおよびC++が何かの知識を持っている(それらのプログラマーである必要はない)。

ターゲットコンテキスト



  • 読者は、UNOとは何か、UNOがLibreOfficeまたはApache OpenOfficeとどう関係しているかを知る。
ト書き
Hypothesizer 7、Objector 1C(前記事から来た)、Objector 2Aがコンピューターの前にいる。


オリエンテーション


Hypothesizer 7
この記事では、UNOとは何か、UNOがLibreOfficeまたはApache OpenOfficeとどう関係しているかを学びます。このシリーズでは、そうした基本から始めて、全体として整合した知識体系を築き上げます。

Objector 1C
そんな抽象的なことは学びたくない。UNOを実際にどうすれば使えるかを知りたいのだ。

Hypothesizer 7
ああ、あなたですか、また...

Objector 1C
悪いか?

Hypothesizer 7
もちろん、そのようなことはございません。...「抽象的」という言葉で何を意図されているのか分かりませんが、基本に立脚した、全体として整合した知識体系がないと、自ら自由に可能性を探求することができません。

Objector 1C
自ら「自由に可能性を探求」したくなんかないんだよ。自分の問題への直接的な解を求めてるんだ。

Hypothesizer 7
えーと、解が誰かからあなたに与られるよう求めているということですか?

ト書き
Objector 1Cは片眉を吊り上げる。

Objector 1C
どういう意味だ?

Hypothesizer 7
私であれば、自分の問題は自分で解決したいと思いますし、少なくとも、解を、よく理解して初めて受け入れるでしょうね。私なら、誰かからこうしろと言われて盲目的に従ったりはしないでしょう...

Objector 1C
俺は誰にも盲目的に従ったりしない!

Hypothesizer 7
そう思いました、それで、基本を学びたいと思われるに違いないと思ったのです。基本は、解をよく理解するのに欠かせませんから...

Objector 1C
基本など学んでいる時間は今ないんだよ。

Hypothesizer 7
多くの場合、必要な基本を学ぶ時間を惜しむと、余分に時間を失います...

ト書き
Objector 1CはHypothesizer 7をにらみつける。

Hypothesizer 7
...が、確かに、別の場合もあります。...あの、このシリーズは基本から特定の手順の説明へと順を追って展開しますが、それをどのような順序でお読みになるかはまったくご自由です(目次から、シリーズの任意の記事に飛ぶことができます)。ほとんどの記事が、基本についての知識を前提条件としていることは申し上げておかなければなりませんが。

ト書き
Objector 1Cは、Hypothesizer 7のように愚かな者にそれ以上話すことは明らかに無意味だと言わんばかりに首を振りながらどこかへ立ち去り、Hypothesizer 7はため息をつく。

Objector 2A
俺がここに来たのは、公式参考ドキュメントの説明がよく理解できなかったからだ。これはあれより少しでもましなのか?

Hypothesizer 7
ああ、そのご質問に直接お答えする前に、誤解を避けるための前置きが必要でしょう。・・・私の意見では、オープンソースソフトウェアのほとんどのドキュメント(いかなる種類の技術ドキュメントでもほとんどと言えるかもしれません)がそれほど満足のいくものではありません。それらは、内容を既に理解している人たちだけが理解できるドキュメントです。多分、著者は、チェックのために自らのドキュメントを読んで言ったのでしょう、「おお、これはとてもよく分かる。これはいいぞ!」。・・・彼らがそれらのドキュメントをとてもよく理解できたのは、それらのドキュメントを読み始める前に、既に、彼らがそれらのドキュメントを理解していたからなのです・・・

Objector 2A
そう・・・

Hypothesizer 7
私がそう申し上げたのは、誰かを責めるためではなく、満足のいく技術ドキュメントを書くことがとても難しく、著者たちは、多分、彼らの時間が許す限りにおいて(彼らのほとんどは多分それらのドキュメントを片手間に書いたプログラマーだったのでしょう)、最善を尽くしたのだと認めるためです。

Objector 2A
よかろう。

Hypothesizer 7
UNOの公式参考ドキュメントは、平均より特に劣るとは私は思いませんが、読者にとっていくらか問題があることを私は否定できません。用語体系が適切ではなく、道理に合わない記述が散見され、そしてお分かりのように、改訂されていない古いドキュメントです。

Objector 2A
俺も、それは否定できんな。

Hypothesizer 7
ご質問にお答えすると、このシリーズを私が書いているのは、私もUNOの公式参考ドキュメントがあまりよく理解できなかったからであり、私の意図は、このシリーズを、先ほど述べた、技術ドキュメントに広く認められる問題(ドキュメントが、まだ話題に精通していない読者をその話題の理解に導くものでないという傾向)に対処したものにすることです。

Objector 2A
それでは、その言葉を守って、分かりやすい説明をしてもらいたいものだな。

Hypothesizer 7
ああ、「分かりやすい」ということについて、明確にしておかなければなりません。説明を「分かりやすく」することは、「単純化」することになりがちですが、これは、私は、誠意を持って退ける努力をします。

Objector 2A
単純化して何が悪いんだ?

Hypothesizer 7
真実をねじ曲げるものであることが悪いのです。つまり、複雑なものは、複雑であるとおりに理解されなければなりません。さもなければ、あなたはそのものを正しく理解していません。

Objector 2A
ふーむ・・・

Hypothesizer 7
単純化することが、多くの人々に愛され、彼らの歓心を買う最短経路である(フェイクニュースのことを考えてみてください)ことは承知していますが、それは、私が誠意を持って避けなけれならないことです。したがって、私が説明を「分かりやすく」しようとする時(私は常にそうしますが)、それは、物事を正確に(物事が実際に複雑であるとおりに)、論理の上でギャップがないように説明しようとすることであって、単純化された虚偽を示すことではありません。

Objector 2A
・・・俺が思うに、それは多くの人には受け入れられないだろうな、一部の変わり者を除いては、俺は、その内の一人かもしれんが・・・

Hypothesizer 7
承知しています・・・


本体


1: UNOとは何か?


Hypothesizer 7
UNO (Universal Network Objects)は、複数のプログラミング言語にマッピングされた1群の仕様であり、UNOオブジェクトとはどのようなものかおよびUNOオブジェクトをどのように操作できるかを規定するものです。

Objector 2A
あんたの定義はひどいな。'UNO'が定義の中で使われているのに、UNOとは何かをどうやって理解できるのか?それに、「複数のプログラミング言語にマッピングされた」が何を意味するのかをどうやって俺が知ることになっているのか?

Hypothesizer 7
ご抗議は分かります、しかし、それが、簡潔な1文でUNOを表現しようとして私が考えついた最善のものでして、それだけで完全に理解されると想定したものではなく、その意味は、以降の説明で明らかになるでしょう。

Objector 2A
そうならせろ。

Hypothesizer 7
えーと、第一に、'UNOオブジェクト'の'オブジェクト'は、オブジェクト指向プログラミングパラダイムの用語体系における'オブジェクト'です。

Objector 2A
すると、オブジェクトはクラスインスタンスだな?

Hypothesizer 7
そうです。そして、UNOオブジェクトは、UNOの仕様を満たすオブジェクトです。

Objector 2A
・・・そうだということは疑わないが、その説明は、UNOオブジェクトがどんなものかを全然教えてくれない。

Hypothesizer 7
勿論です。UNOオブジェクトは、他のプログラミング言語ランタイム環境から操作できるオブジェクトです。

Objector 2A
「他のプログラミング言語ランタイム環境」とは何だ?

Hypothesizer 7
プログラミング言語ランタイム環境は、あるプログラミング言語のあるランタイム環境です。

Objector 2A
・・・あんたの説明は、説明するべき用語の中の単語をそのまま並べているだけにしか思えん。

Hypothesizer 7
例えば、1つのJVM(Javaのランタイム環境)は、1つのプログラミング言語ランタイム環境です。

Objector 2A
2つのJVMが1つのコンピューターで動いていたらどうだ?

Hypothesizer 7
それらは、2つの別々のプログラミング言語ランタイム環境です。

Objector 2A
C++のあるプログラムプロセスが、同じコンピューターで動いていたらどうだ?

Hypothesizer 7
それは、また別のプログラミング言語ランタイム環境です。

Objector 2A
要は、プログラミング言語ランタイム環境はプロセスだろう?

Hypothesizer 7
必ずしもそうではありません。C++のあるプロセスがJNIを通してそのプロセス内に1つのJVMを作るとき、C++のプログラミング言語ランタイム環境とJavaのプログラミング言語ランタイム環境が、その1つのプロセス内にあります。

Objector 2A
ああ、・・・それで?

Hypothesizer 7
あるJVM(1つのプログラミング言語ランタイム環境)にただの普通のオブジェクトがあっても、別のJVM(別のプログラミング言語ランタイム環境) から操作できませんが、前者のJVMの中のUNOオブジェクトは、後者のJVMから操作できます。

Objector 2A
前者のJVMの中のUNOオブジェクトはどれでも、後者のJVMから操作できるのか?

Hypothesizer 7
後者のJVMは、UNOオブジェクト(正確に言うと、UNOオブジェクトの'UNOプロキシ'(UNOプロキシとは何かは、次の記事(近日公開されます)で学びます))への参照を取得できれば、そのUNOオブジェクトを操作でき、できなければ、できません。

Objector 2A
それでは、後者のJVMは、どのUNOオブジェクトへの参照を取得できるのか?

Hypothesizer 7
後者のJVMは、UNOオブジェクトへの参照を、ある一連のステップ(将来の記事で学びます)を通じて取得します。要は、後者のJVMがそのようにしてUNOオブジェクトへの参照を取得できるかどうかだけの問題です。

Objector 1C
お前の抽象的な説明は悪意に満ちてる!「ある一連のステップ」とは何だ?全然イメージができん!

Hypothesizer 7
ああ、ここにいたのですか・・・

Objector 1C
悪いか?

Hypothesizer 7
もちろん、そのようなことはございません。・・・あの、あなたを喜ばせるイメージをわかせるが不正確であるような叙述を私はしたくないのです。私が詳細を叙述する際は、その叙述は正確でなければならず、それは、正確であるためには、一定の長さを必要としますが、この記事に適切に組み込むことができません。

Objector 1C
・・・結局、俺を喜ばせたくなわけで、それが悪意だ。

Hypothesizer 7
まあ、嘘をつくことであなたにおもねるのを潔しとしないことが悪意であるならば、私は、悪意を持たなければならないでしょう・・・

ト書き
Objector 1CはHypothesizer 7をにらみつける。

Objector 2A
あんたらのくだらん口論がなによりも俺の時間をむだにしている!説明に戻れ!

Hypothesizer 7
大変、申し訳ございません。

Objector 2A
「複数のプログラミング言語にマッピングされた」というのはどういう意味だ?

Hypothesizer 7
UNOの世界における複合データタイプ(インターフェイス、構造体等(クラスは違います))は、UNOIDLと呼ばれるデータタイプ定義言語で定義されます。

Objector 2A
「データタイプ定義言語」というのは、データタイプを定義できるがロジックは記述できない言語のことか?

Hypothesizer 7
そうです。それが、プログラミング言語とは呼ばなかった理由です。

Objector 2A
プリミティブデータタイプはどうなるのか?

Hypothesizer 7
プリミティブデータタイプは、すべて事前定義されているので、UNOIDLでは定義されません。

Objector 2A
クラスはどうなる?

Hypothesizer 7
UNOの世界にクラスはありません。

Objector 2A
はあ?それは問題だろう?だって、クラスは必要だろう・・・

Hypothesizer 7
えー、順を追って説明させてください。

Objector 2A
そうしろ。

Hypothesizer 7
プリミティブデータタイプおよび複合データタイプは各プログラミング言語の世界へマッピングされます。

Objector 2A
「マッピングされ」るとはどういう意味だ?

Hypothesizer 7
UNOの世界における各データタイプに対して、各プログラミング言語の世界に、単一の対応するデータタイプがあります。

Objector 2A
そのマッピングは1対1なのか?

Hypothesizer 7
厳密には違います。例えば、UNOの世界における'long'と'unsigned long'(実は、使用不推奨になっています)の両方が、Javaの世界における'int'にマッピングされます。

Objector 2A
それで問題が起こらないのか?つまり、'int'のJavaデータタイプに対するUNOデータタイプが推測できないだろう・・・

Hypothesizer 7
起こりません、しかし、1つ複雑な事情があります。

Objector 2A
「複雑な事情」?

Hypothesizer 7
ほとんどの場合、推測は一直線です。例えば、UNOIDLで、'unsigned long'の引数を持つメソッドを持つ、あるUNOインターフェイスを定義すると、この引数は、Javaの世界では、'int'引数にマッピングされます。

Objector 2A
それで?

Hypothesizer 7
この引数にセットされた'int'Javaデータに対するUNOデータタイプは、疑いなく'unsigned long'です、なぜなら、UNOIDLに明示的にそう記されているからです。

Objector 2A
ああ・・・、確かに。

Hypothesizer 7
ただ、正しい値を使うよう注意しなければいけないだけです。例えば、Javaの世界の-1'int'値が、UNOの世界での2 31 - 1 'unsigned long'値を表わします。

Objector 2A
ははあ。

Hypothesizer 7
しかし、UNOIDLでの引数タイプが'any'の場合、事は、それほど直線的ではありません。

Objector 2A
「'any'」?

Hypothesizer 7
'any'は、任意のデータタイプの任意の値を保持できる変数タイプ(データタイプではないことに注意してください)です。

Objector 2A
「データタイプではない」とはどういう意味だ?

Hypothesizer 7
'any'タイプのデータなどというものはありません、'long'タイプのデータ、'unsigned long'タイプのデータ等を、'any'タイプの変数にセットすることはできますが。

Objector 2A
ああ、分かった。

Hypothesizer 7
それでも、'any'が使われた場合でも、推測はどうにか行われます、複雑なので、この記事では説明できませんが。将来の記事で学びます。

Objector 2A
オーケー。

Hypothesizer 7
各クラスは、1つのプログラミング言語で定義されます。

Objector 2A
ふむ?ふーむ。すると、そのクラスは、その単一のプログラミング言語にのみ存在し、UNOの世界にはなく、他のプログラミング言語の世界にもない・・・

Hypothesizer 7
そうです。クラスは実装であり、そのクラスが定義されたプログラミング言語のランタイム環境内でのみインスタンス化されます。他のランタイム環境は、それらのインスタンス(UNOオブジェクト)を、そのクラスに実装されたUNOインターフェイスを通じてリモートから('別のコンピューターから'という意味での'リモート'では必ずしもなく、'別のランタイム環境から'という意味)操作します。

Objector 2A
したがって、他のプログラミング言語の世界もUNOの世界もそのクラスを持っている必要がない・・・。データタイプがそうして共有されているのは分かるが、2つのランタイム環境を接続し、各ランタイム環境からUNOの世界へ、UNOの世界から各ランタイム環境へとデータをコンバートし、2つのランタイム環境の間でメソッド呼び出しを運び値を戻すなんらかのメカニズムがなくてはならないはずだ。

Hypothesizer 7
はい、なくてはなりませんし、あります。それは、'ブリッジ'と呼ばれています。ご想像できる通り、ブリッジは、2つの端を持ち、それぞれの端は、それぞれのプログラミング言語ランタイム環境で動作し、他方の端と通信します。

Objector 2A
すると、UNOがマッピングされる各プログラミング言語は'ブリッジ端'の実装を持たなければならない・・・

Hypothesizer 7
それが、UNOの全体像です。


2: How Is UNO Related to LibreOffice or Apache OpenOffice? UNOはLibreOfficeまたはApache OpenOfficeとどう関係しているか?


Hypothesizer 7
UNOは1群の仕様であり、UNOをあるプログラミング言語で実際に使うためには、そのプログラミング言語でのUNOの実装が必要であることに注意してください。

Objector 2A
だからそういうライブラリがあるんじゃないのか?

Hypothesizer 7
実は、純粋な'UNO実装のライブラリのパッケージ'はなく、UNO実装を含むライブラリ を含む2つのアプリケーションがあります。それらが、LibreOfficeおよびApache OpenOfficeで、これらは、それ自体、UNOに基づいて構築されています。

Objector 2A
それら2つのアプリケーションがUNOに基づいて構築されているから、俺のプログラムは、それら2つのアプリケーションを、それら2つのアプリケーション内に生存するUNOオブジェクトを操作することで、操作できる・・・

Hypothesizer 7
そうです。それが、LibreOfficeおよびApache OpenOfficeを、他のオフィススイートよりも広範に操作できる理由であり、そのように広範に操作できることが、LibreOfficeまたはApache OpenOfficeを私たちが使う理由です。

Objector 2A
LibreOffice、Apache OpenOfficeの相互の関係を知りたいのだが・・・

Hypothesizer 7
簡潔に言うと、LibreOfficeおよびApache OpenOfficeは、OpenOffice.orgという単一のオープンソースオフィスソフトウェアスイートから派生した2つのオープンソースオフィスソフトウェアスイートです。

Objector 2A
ああ、だから、OpenOffice.orgが公式参考ドキュメントに頻繁に出てくるわけだ。

Hypothesizer 7
あのドキュメントはOpenOffice.org用に書かれた古いドキュメントなのです。

Objector 2A
LibreOfficeとApache OpenOfficeは似ているが、違っている。・・・どのように違うのか?

Hypothesizer 7
正直、よくは知りません(Office Open XMLフォーマットのファイルやそれらに近親のMicrosoft OfficeフォーマットのファイルをApache OpenOfficeが書けないのは知っています)、しかし、それらが大きくは違わないという前提で私は話してします。実際、私は常に、自分が使っているLibreOfficeに基づいて、叙述がApache OpenOfficeにも当てはまるだろうという想定のもとに話をするでしょう。叙述が何かしら当てはまらない場合は、・・・私は残念に思うでしょう。

Objector 2A
・・・あんたが残念に思っても私には何にも助けにならない。

Hypothesizer 7
おっしゃるとおりです、その点についても私は残念に思うでしょう。

Objector 2A
・・・それなら満足だ。

Hypothesizer 7
とにかく、LibreOfficeまたはApache OpenOfficeの構造についてもっとよく知っておけば、LibreOfficeまたはApache OpenOfficeを活用するのに助けとなるでしょう。

LibreOfficeの主要部はC++で書かれています。

Objector 2A
LibreOfficeプロセスの主要部はC++プログラミング言語ランタイム環境で動いているということだな。

Hypothesizer 7
そうです。他方で、LibreOfficeでは、いくつかの他のプログラミング言語のそれぞれのためのライブラリが用意されています。

Objector 2A
ああ、マッピングされたデータタイプ群と'ブリッジ端'の実装だろう?

Hypothesizer 7
そうです。アプリケーション機能の実装は、C++プログラムの中にのみあり、他のプログラミング言語のライブラリの中にはないことに注意してください。

Objector 2A
つまり、俺のJavaプログラムがスプレッドシートドキュメントファイルを読み書きする際、俺のプログラムは、それらのファイルを直接読み書きするのではなく、LibreOfficeプロセスの主要部の中に生存するUNOオブジェクトを操作し、それらのUNOオブジェクトがスプレッドシートドキュメントファイルを読み書きする・・・

Hypothesizer 7
そうです。その理解が重要です。

加えて、LibreOfficeプロセスは、その内部に、JVM、Basicランタイム環境、Pythonランタイム環境等のいくつかの他のプログラミング言語ランタイム環境を持つことができます。

Objector 2A
「でき」るとはどういう意味だ。

Hypothesizer 7
それらの各々は、有効化したり無効化したりできます。

Objector 2A
ふーむ、それでは、俺のJavaプログラムは、LibreOfficeプロセス内のJVMで動作させることも、外部JVMで動作させることもできる。何が違うんだ?

Hypothesizer 7
LibreOfficeプロセス内のJVMとそのLibreOfficeプロセスのC++主要部ランタイム環境の間には、事前準備された、プロセス内ブリッジがあります。

Objector 2A
「事前準備された」というと?

Hypothesizer 7
そのブリッジは、あなたが作るのではありません。LibreOfficeプロセスが、JVMを初期化する際に作るのです。

Objector 2A
外部JVMとLibreOfficeプロセスのC++主要部ランタイム環境の間にはプロセス間ブリッジがあるということのようだ・・・

Hypothesizer 7
あなたの外部プログラムは、LibreOfficeプロセスのC++主要部ランタイム環境の間に、そのプロセス間ブリッジを確立することになります。

Objector 2A
それだけか?それらのブリッジが確立された(LibreOfficeプロセスによってであろうが俺の外部プログラムによってであろうが)後、UNOオブジェクトの操作は、プロセス内ブリッジを通すかプロセス間ブリッジを通すかにかかわらず、透過的に行なうことができるのか?

Hypothesizer 7
うーん・・・、基本的にはそうです。

Objector 2A
はっきりしない答えだな・・・

Hypothesizer 7
実は、プロセス内ブリッジを使うのとプロセス間ブリッジを使うのとでは、ある重要な違いがあります、しかし、それは、多くの、えー、無頓着な人々は気付きもしないものです。

Objector 2A
自分が特に無頓着だとは俺は思わんが・・・。それで、その違いとは何か?

Hypothesizer 7
うーん、それをここで説明するのはとても困難です。それについて話す前に、UNOの基本的構成要素とメカニズムを学ばなければなりません(将来の記事で学びます)・・・

Objector 2A
・・・いいだろう。

Hypothesizer 7
全てのUNOプログラミング言語実装がUNOの機能をフルサポートしているわけではないことに注意してください。例えば、あるUNOプログラミング言語実装は、プロセス間ブリッジをサポートしていないかもしれません。

Objector 2A
どのUNOプログラミング言語実装が、どの機能をサポートしているのか?

Hypothesizer 7
JavaおよびC++の実装はフル機能をサポートしていますが、正直、他のものが厳密にどの機能をサポートしているかを私はよく知りません。Python、Basic、BeanShell、JavaScriptの実装は、プロセス内ブリッジをサポートしていますが、プロセス間ブリッジについては私はよく知りません。Microsoft .NET Framework実装は、プロセス間ブリッジのみをサポートしているように思われます。実のところ、ある種のプログラミング言語実装は、ある限られた形でのみで使用されるように想定されていて、他の形で使用することについてのドキュメントがありません。

Objector 2A
ああ、多分、他の形で使用することに関心のある人が多くは、たとえ皆無でなくても、いないんだろうな。


参考資料


  • Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide
<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>