[IM]コンテキストに対応したモデルの実装

以前に「コンテキストの内部実装」という記事を書きましたが、コンテキストというか、正確には、コンテキストに対応したモデルの実装について、書いておきます。内部のソースを読んでいない人にはなんのことかさっぱり分からないと思います。

この仕組みを実装しているのは、INTER-Mediator-Context.jsファイルにあるIMLibContextクラスです。そこにあるいくつかのプロパティのデータ構造は、コードを読む場合や改造では絶対に必要な知識なので、一度まとめておこうと思っていました。

以下、「recKey」は、レコードを特定する文字列で、「キーフィールド=その値」という文字列です。たとえば、”id=3″のような文字列に相当します。そして、以下の「key」はすべてフィールド名の文字列が入ります。「portal」はFileMaker Serverを使う場合に、定義ファイルで’portal’=>trueにしている場合の、関連レコードに対応する外部キーの値です。FMS以外ではportal引数は渡されません。以下、portalが有る場合とない場合のデータ形式を記述します。

まず、IMLibContextクラスのプロパティstoreには、実際のフィールドのデータを記録します。store自体がオブジェクトで、以下のようにアクセスすることで、フィールドの値Valueにアクセス可能です。

this.store[recKey][key]→Value
this.store[recKey][key][portal]→Value

次に、プロパティbindingです。これは、データベースのフィールドが、どの要素に結びついているのかを記録するオブジェクトです。データベースから、バインドしているノードを求めるために用意しています。右辺は、オブジェクトの配列になっています。IdValueはバインドしたノードのid属性値です。Targetは、そこでのターゲット指定です。なお、Target指定は “” の場合もありますが、そのときにはTargetの値は “_im_no_target” という文字列にしています。

this.binding[recKey][field]→[{id: IdValue, target: Target}, ...]
this.binding[recKey][field][portal]→[{id: IdValue, target:Target}, ...]

次はcontextInfoプロパティです。こちらは、バインドしたノードから、データベースのどのレコードの、どのフィールドなのかを求めるためのものです。要するに逆テーブルです。thisと、.contextは同じものですが、thisが使えない状況を考慮してプロパティを作ってあります。

this.contextInfo[nodeId][target].context→コンテキスト自身
this.contextInfo[nodeId][target].record→recKeyの値
this.contextInfo[nodeId][target].field→keyの値
this.contextInfo[nodeId][target].portal→portalの値

これらの3つが主要なデータ構造となります。

FileMaker 13で、XMLおよびXSLTによる出力

久しぶりにタイトルのような事をやりました。この記事のハイライトは、変数でXSLTファイルの位置を指定できるようになったものの、エラーが出るという事象に遭遇しますが、その対処方法が分かったということです。

XML出力は、FileMaker 5くらいからありますし、出力するXMLデータにXSLTを適用して、テキストやらHTMLやらを生成することができるので、ちまちまと文字列処理を書かなくてもいいので便利です。XSLTの習得が大変という話もありますが、今時この種の情報は「基本知識」でしょうから、勉強すればいいのです。私自身は幸いにも、今はなくなってしまったXSLTでのWeb公開の時代に、かなり勉強していたし実稼働させたソリューションもあったので、自分的にはXSLTはOKです。この記事では、XMLやXSLTあるいはそれらを利用するFileMakerの機能については詳細には説明しませんので、必要な方は予習をしてください。

現実にXML/XSLTを使うとき、当然ながらXMLはテーブルを出力するときのフォーマットなので、テーブルから生成されることになります。一方、XSLTはどうでしょうか? 確実は方法は、Webサーバ等に配置して、URLで指定することですが、データベースファイルと別の管理対象ができて不便です。そこで、XSLTのテキスト自体をテーブルのフィールドにテキストとして保存しておくことで、データベースと一体化して管理ができて便利です。ただし、そのXSLTのテキストを利用するときにはファイルにしなければなりません。現実にはスクリプトを組むとして、1フィールド、1レコードだけのタブ区切りで出力すれば、余計な “” などは含まれません。ただし、その1フィールドに、改行が入っていると、コード番号12のものに置き換えられます。後から変更するのは面倒なので、XSLTのテキストから改行を除去する計算式を設定した計算フィールドをエクスポートすればいいのです。もちろん、XSLT内では改行の有無で動作が変わらないにしなければなりません。

さて、そこで、このXSLTファイルをどこに保存するのかということですが、WindowsでもMacで稼働できるようするには、テンポラリフォルダがいいのではないでしょうかということで、次のようなスクリプトで変数にパスを入れることにしました。順当な方法かと思います。

スクリーンショット 2014-06-26 10.47.20

この変数$templateJの結果を利用して、XSLTのテキストをエクスポートします。前に説明したように、スクリプトで、1レコードのみを対象レコードとして、改行を省いたテキストのフィールドだけをタブ区切りで出力します。出力ファイルに、変数$templateJを指定します。

ここで、XSLTによる変換をスクリプトのどこかで組み込むとします。スクリプトステップの「レコードのエクスポート」で、「出力ファイルの指定」を行い、OKボタンを押すと、ファイルタイプが「XML」の場合はさらに次のダイアログボックスが表示されます。ここで「XSLスタイルシートを使用」を選択し、ファイルを指定するわけですが、「ファイル」だとダイアログボックスが出て来て、特定のファイルの指定が必要です。Get ( テンポラリパス ) は一定のパスではない模様ですし、Win/Macでパスは違います。なので、「計算」を選択して、前の変数$templateJを指定して、実際に動かしてみます。ボタンと計算式の文字列が重なっているところにFileMaker社のこの機能への姿勢が見て取れます。

スクリーンショット 2014-06-26 10.46.40

すると、XMLのエクスポートをするときに、次のようなエラーが出ます。SAX(XMLのパーサ)のエラーがそのまま見えていて意味が分かりにくいですが、ようするにファイルが見つからないということです。Windowsでは、実際に見つからなかったパスも見えています。

スクリーンショット 2014-06-26 10.49.33

変数$templateJで出力し、その直後に変数$templateJでファイル参照して見つからない。ようするにバグなのですが、バグで使えません、以上ということでは前に進みません。バグは直らない可能性もあるからです。

そこで、変数$templateJの内容を、MacとWindowsで調べ見ました。Macだと、「/Macintosh HD/var/tmp/….」みたいになっています。Windowsだと、「/C:/Users/msyk/….」となっています。まず、Macは、明らかにパスの最初のコンポーネントを取り去れば、存在可能なUNIXパスになります。Windowsは…ともかく、まず、XSLTのテキストをエクスポートした後、以下のような「変数を設定」スクリプトステップを追加して、最初のコンポーネントを省いてみました。

スクリーンショット 2014-06-26 10.46.58

Macでは、予想通り、それでエラーなく動きました。一方、Windowsは別の対策をしないといけないかと思ったのですが、なんと、ちゃんと動きました。UNIXみたいなパスの与え方でどうやら動くようです。

XSLTのTipsを少し書いておきましょう。関連レコードのフィールドは、TOさえあれば出力できると思っていたら、ポータルに展開しないと出力されません。ポータルがない場合は、ちゃんと警告メッセージを出して、最初のレコードの値だけが出力されると言われます。ということで、ポータル作成はさぼれません。

関連レコードのデータは、たとえば2つのフィールドがあるとして、関連レコードが3つあると、次のように出力します。このノードの上位ノードのタグはROWになります。

<COL><DATA>1</DATA><DATA>2</DATA><DATA>3</DATA></COL>
<COL><DATA>abc</DATA><DATA>def</DATA><DATA>ghi</DATA></COL>

上記の2つのフィールドの番号を1、2とします。ROWタグがカレントノードのとき、上記のデータを展開するのにfor-eachを使うのですが、同じポータルにある関連レコードがいくつかるとき、for-eachをそのうち1つのフィールドに対して行います。次のような感じです。ネームスペースの略号は、xsl、fmrとしています。

<xsl:for-each select="fmr:COL[1]/fmr:DATA">
    <div>
        <xsl:value-of select="." />
        <xsl:value-of select="../../fmr:COL[2]/fmr:DATA[position()]" />
    </div>
</xsl:for-each>

最初のfor-eachは普通にDATAタグが複数あるので、それを1つ1つ取り出します。3行目の「.」によって、1つ目のフィールドの現在のDATAのテキストを取り出すので、「1」「2」「3」という値が順次取り出されます。2つ目のフィールドは、4行目にあるように、XPATHの記述で、カレントノードからROWまで「../..」でさかのぼり、そこから、COL、DATA集合へと下ります。そして「position()」というのは関数です。for-eachでループしているときに、何番目なのかを示す値を返します。これで、「abc」「def」「ghi」という文字列が順次得られます。

最後に大サービスで(笑)、FileMakerのXML出力向け(ただし、FMRXMLRESULTスキーマ)の汎用的なテンプレートを書いておきましょう。コピペして、あとはデータの順序に合わせてFMPXMLRESULTやROWタグ要素に対応するテンプレートにHTML等で出力テンプレートを書くだけです。

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:fmr="http://www.filemaker.com/fmpxmlresult"
    exclude-result-prefixes="xhtml fmr">
<xsl:output encoding="UTF-8" method="xml" indent="yes"
   omit-xml-declaration="yes"/>

<xsl:template match="fmr:ERRORCODE | fmr:PRODUCT | fmr:METADATA">
</xsl:template>

<xsl:template match="fmr:FMPXMLRESULT">
    <html><body><table>
       <tr><th>Name</th><th>Activity</th></tr>
       <xsl:apply-templates />
    </table></body></html>
</xsl:template>

<xsl:template match="fmr:ROW">
    <tr>
        <td><xsl:value-of select="fmr:COL[3]/fmr:DATA[position()]" /></td>
        <td>
            <table>
                <xsl:for-each select="fmr:COL[1]/fmr:DATA">
                   <tr>
                       <td><xsl:value-of select="." /></td>
                       <td><xsl:value-of select="../../fmr:COL[2]/fmr:DATA[position()]" /></td>
                   </tr>
                </xsl:for-each>
             </table>
         </td>
    </tr>
</xsl:template>

ノートをつけてみた

コンピュータ使いにとって、メモにはこだわりがあるのが普通だろう。情報機器を常日頃から使いこなしているのなら、スマートにメモを取るなんてことは当然のことだ。…といいたいところではあるが、実際にはどうだろう? あれこれ試しては新しいサービスやソフトに乗り換えてみたり、戻ってみたりと試行錯誤する日々ではないだろうか?

そんな中、STAP細胞の真偽を巡って「ノート」という存在が明らかになった。そういえば、大学のときも化学系の連中はノートを使っていたような記憶があるが、私は電気系であり、あまり実験ノート的な縛りはなかった記憶がある。工学系はやはり再現性が最も基本だから、ノートをエビデンスとして使うということより重要なことがあるのだが、それはさておき、ふと思って日々の仕事の内容を「ノート」を付けることでどうなるかを見てみた。ただ、1冊は以前からずっと使っているのだが、案件用に1冊追加し、それまでのノートはそれ以外の用途と2冊を使う事にした。それまでの記録の付け方は後に説明しよう。

さて、5月の1ヶ月間でどのくらいのページになったかと言えば、案件用23ページ、その他9ページとなった。もちろん、ノートにすべてを書いているわけでなく、Macに向かって打ち込む以外の「記述」をすべてノートでやってみた結果である。とりとめのないメモや、ざっくりとした図や表などをノートに書いて行った結果である。

スクリーンショット 2014-06-12 16.17.58

それまでどうしていたかと言うと、まず、案件ごとのメモは、きわめてシンプルに、その案件のファイルがあるフォルダにテキストファイルで残していた。URLやアカウント、情報の断片など、とにかくばんばんとコピペする。

そして、まとまった情報は、EvernoteとFileMakerで作ったデータベースに保存する。当初はFileMakerだけだったのだが、iOSで共有するとなるとEvernoteの方が手軽である。特に、URLを入れればリンクになるとか、そういうのはFileMakerではできないわけではないが、はっきり言ってたんに面倒になるだけなので、現在は作る文書によって使い分けている。FileMakerはどちらかと言えば書庫的であり、EvernoteはWiki的に使っている。複数人が関わるプロジェクトではBacklogを使い、場合によってはRedmineに入ることもある。

さらに、「紙切れ」を用意している。最近は、日めくりの裏を永年愛用している。スタートレックやギターの日めくりを買っており、翌年はメモとして活躍するのである。

思い付いたとき、そこでテキストファイルが開いていれば書き込み、Evernoteが開いていれば書き込み、それも面倒なときにはまずは紙切れに書いておく。紙切れに書いたものは、一定期間後に電子的な手段にコピーするが、その一定期間を過ぎて不要になったものまではわざわざ入力はしないで捨ててしまう。どうでもいい情報は適当にスクリーニングされるということだ。この「一定期間」を置くというのはなかなかみそで、メモ情報が爆発しないという利点もあると考える。もちろん、面倒を避けているという消極的な意味もあるが、短期間で情報価値がなくなるものは、長期間後に復活する可能性は極めて低いと言っていだろう。

ノートにして不便な事は、1つの案件ベースでのトレースがしづらくなるということだ。そうやってノートを分けるということをすると、きっと今度はノートだらけになるのだろう。案件事にテキストファイルを作っている理由は、トレースがしやすいからでもあるし、何年か後に開くことを考えての事だ。

一方、ノートを書くという習慣は、考えたことに対して自己評価をする機会が与えられる感じがする。ガシガシと打ち込んでしまうとそれで終わってしまうのだが、手で文字を書くという時間の幅が考える余地を生み出すように思える。それはそれで悪い事ではない。

さて、これからどうしようか? やはり全面的にノートにするより、今までの方法にじわじわ戻すつもりである。コンピュータ使いとしては「ノートは不要」と言いたいところだが、ノートにはノートのいいところもある。iPadでJot!で手書きしていた時期もあるものの、やはりノートの方が疲れない気がする。だけど、ノートで全て行うのは、むしろきちんと整理ができない。結局のところは使い分けということになるのだろう。そして、日々の記録方法を改善することも仕事のクオリティを高めることになるのじゃないかと改めて感じる。

[IM]JavaScriptコンポーネントのプラグイン

以前から、HTMLエディタのtinyMCE、コードエディタのCodeMirrorや独自作成したファイルアップロードコンポーネントを使えるようにしていたのですが、なんとか「プラグイン」的に使える状態になったので、一度ドキュメントを作成します。JavaScriptで作ったコンポーネントに、データベースにあるフィールドの値を表示し、修正するとそれが書き戻される仕組みを提供します。ただし、コンポーネントごとに、初期化の方法は違うので、その部分を吸収するプラグインを作らないといけません。

JavaScriptコンポーネントの使い方

まず、JavaScriptのコンポーネントを使いたい場合には、次のように、data-im-widget属性にキーワードを書きます。プラグインができていればこれだけです。

<div data-im="testtable@text1" data-im-widget="tinymce"></div>

ここで、tinyMCEを使うにはプラグインが必要ですが、これについては、すでにINTER-Mediatorの中にあります。Samples/Sample_webpage/tinymce_im.jsがそれなので、たとえば、ページファイルのヘッダ部に、次のような記述を行ってtinyMCE自身の読み込みと、プラグインの読み込みを行っておきます。もちろん、パスは適切なものを指定してください。

<script type="text/javascript" src="tinymce/js/tinymce/tinymce.min.js"></script>
<script type="text/javascript" src="tinymce_im.js"></script>

Ver.4.4現在、tinyMCE、CodeMirror、それから独自に作ったファイルアップロードコンポーネント(Samples/Sample_webpage/fileupload_MySQL.htmlがサンプル)が利用可能です。

JavaScriptコンポーネントプラグインの作り方

プラグイン(前記のtinymce_im.jsに相当)は、JavaScriptで記述します。もちろん、tinymce_im.jsもサンプルとして参照する必要があるでしょう。

プラグインのファイルでは、IMParts_Catalog変数のオブジェクトに、プラグインのオブジェクトを追加します。このときのキーが、data-im-widget属性に指定するキーワードとなります。以下はその基本構造です。

IMParts_Catalog["tinymce"] = {
    instanciate: function (parentNode) { },
    ids: [],
    finish: function (update) { }
}

右辺のオブジェクトは、instanciateとfinishという2つのメソッドを持つ事が重要です。INTER-Mediatorは、ページ合成時に、im-data-widget属性があるノードを見つけると、そのノードを引数にとって、instanciateメソッドを呼び出します。

一方、ページ合成の最終段階、つまり、DOMオブジェクトが確定してページ上に存在する状態になった後に、finishメソッドが呼び出されます。結果的に、im-data-widget属性が設定された要素×レコード数の回数instanciateメソッドが呼び出され、最後に1回finishが呼び出されます。

プラグインの作業として必要なこと

この2つのメソッドが行うことは、コンポーネントに対するゲッタおよびセッタメソッドをそれぞれ展開したコンポーネントに対して設定することです。また、対応コンポーネントのid属性値を得るメソッドも実装します。たとえば、instanciateメソッドに記述するとしたら、次のようになります。instanciateメソッドを呼び出されたときの引数parentNodeあるいはコンポーネントのルートの要素に対して、以下の決められた名称のメソッドを実装します。メソッドの中身はtinyMCEの場合の例です。

parentNode._im_getComponentId = function () { // data-im-widgetのある要素に設定
    var theId = newId;
    return theId;
};
parentNode._im_setValue = function (str) { // data-im-widgetのある要素に設定
    var targetNode = newNode;
    targetNode.innerHTML = str;
};
targetNode._im_getValue = (function () { // コンポーネントのルートの要素に設定
    var thisId = targetId;
    return function () {
        return tinymce.EditorManager.get(thisId).getContent();
    }
})();

instanciateメソッドでの作業

通常、JavaScriptのコンポーネントは、特定の要素にidやclass値を適当に与えて、その要素の中に必要なオブジェクトを詰め込むといった動作をします。つまり、起点となる要素を用意しておき、そこに必要なオブジェクトを追加します。tinyMCEだと、手軽な作り方はTEXTAREAタグ要素を用意することですが、ページファイル上に記述した要素がどんな種類のタグ要素でもいいように、data-im-widget属性がある要素の子要素にTEXTAREAタグ要素を作り、その要素をtinyMCEで初期化するようにしています。

そのTEXTAREA要素のid属性は、適当に付けます。targetNodeで参照されるリピーター内の要素は、すでにid属性が設定されているので、そのid値に適当な文字を追加すれば、一意なid属性になります。_im_getComponentIdメソッドは、ここでのTEXTAREA要素に付けたidを返します。

なお、instanticateメソッド中は、まだ、リピーターはエンクロージャーに挿入されておらず、documentからたどれない状態になっています。その場合、初期化をしてもうまく動作しないと思われます。従って、instanciateメソッドでは、元になるTEXTAREA要素を作り、id番号を振り、そのid番号をidsプロパティの配列に追加して、必須のメソッドを定義するところまでしかできないのが一般的かと思います。idsプロパティはなくてもいいのですが、この後のfinalizeメソッドでそれぞれの要素を初期化するために、初期化すべき要素を後から特定できるようにするために、instanciateで作成した要素のidを残します。

instanciateメソッドの段階で実際に利用されるのは、_im_getComponentIdメソッドと_im_setValueメソッドなので、_im_getValueメソッドは実際には設定する必要はありません。_im_setValueメソッドについては、JavaScriptコンポーネントが初期化前であることを考慮して、機能する前の状態での値設定が可能なプログラムを記述する必要があります。

finalizeメソッドでの作業

この段階では、全ての要素がdocument配下にいるので、JavaScriptコンポーネントの初期化を実際に行います。なお、初期化した結果、ゲッタやセッタの動作を変えたい場合は、設定をしなおします。JavaScriptのコンポーネント内で修正した結果をデータベースに書き戻すには、_im_getValueメソッドを、初期化が終わった後の状態でのゲッタとして動作するように設定をする必要があります。単にデータベースに書き戻すだけでいいのなら、ゲッタの設定のみでかまいません。以下は、tinyMCEの例で、idsプロパティにコンポーネントのid属性値が配列として残されています。1つ1つの要素に対して、_im_getValueメソッドを追加しています。

 for (var i = 0; i < this.ids.length; i++) {
     var targetNode = document.getElementById(this.ids[i]);
     var targetId = this.ids[i];
     if (targetNode) {
         targetNode._im_getValue = (function () {
             var thisId = targetId;
             return function () {
                 return tinymce.EditorManager.get(thisId).getContent();
             }
         })();
     }
 }

tinyMCEのプラグインは、ページ上にあるすべてTEXTAREAをHTMLエディタにしてしまう動作で初期化するので、tinyMCE.initメソッドを呼び出すだけです。コンポーネントによっては、個別にオブジェクトをidsプロパティから取得したid値で参照して、それぞれに何らかのメソッドを適用しないといけないかもしれません。

結果的に、それぞれのJavaScriptコンポーネントごとにうまく初期化をしないといけませんが、場合によってはフレームワークの更新も必要になるかもしれません。

自分でJavaScriptコンポーネントを作る場合

自分で1からコンポーネントを作る場合は、以下のプラグインの骨格を作り、後は自由につくっていいでしょう。このクラスにメソッドを集めてもいいですし、他のファイルから参照してもかまいません。

IMParts_Catalog["myjscomponent"] = {
    instanciate: function (parentNode) { },
    ids: [],
    finish: function (update) { }
}

ブログを整理しました

会社員時代はブログは書いていなかったのですが、独立してしばらくしてから、だいたい2010年あたりからブログを書いていました。最初は、Mac OS X Server Snow LeopardのWikiを使っていたのですが、Lionへはうまく移行できたものの、その後に失敗(アカウントを消した)とか、Mountain Lionのときに変な場所に移行したとか、いろいろあって、2013年2月からはWord Pressで運用しています。

さらに、Mavericksに移行しようとして決定的な失敗をしてしまい(とほほ)。「過去のブログを見るだけ」のWebサーバとしても機能しなくなりました。FileMaker ServerをWebで動かしているのでどっちに転んでもやっぱり両方の用途に使うのはかなりしんどいです。ということで、日曜日に過去のブログをサルベージしました。PostgreSQLのデータベースからダンプして、手作業も入りながらのコピペで移行しました。INTER-Mediatorのブログは思考のプロセスを思い出すのに必要なこともあり、この関連記事は全部以降しました。他に、受けたとか、今でも意味があるというのはみんな移行しましたが、OS X Server関連はもういいかということで省略としました。

そんなわけで、過去の記事が突然、Twitter公開とかでよみがえってしまってすみませんでした。これで、ここ何年かの消えた記事が復活して一安心です。

FileMaker Server 13とOS X ServerのWeb

FileMaker Server 13と、OS X ServerのWebサービスの共存は基本的にはできません。となると、OS X ServerのWikiとかはあきらめるか、設定ファイルをあれこれということになりますが、ともかくいったんあきらめてFMS13を入れるといういう場合、80番と443番ポートが使われているのでインストールができないというメッセージに出くわします。

Webサービスを止めても、Wikiを止めてもまだそのメッセージが出ます。コマンドで落としてインストールしていたりしましたが、再起動したらやっぱりFMS側がだめになってどうしようもありません。徹底究明した結果、なんと、WebDAVが動いていました。ファイル共有でWebDAVを利用すると、Webサービスがオフでも、80番ポートを使ったhttpdが動いています。

では、WebDAVを全部オフにして再起動してみます。それでも、httpdは動いています。どうやら一度オンにすると、テコでも動くようです。そこで、すべての共有ポイントでWebDAVがオフになっていることを確認して、以下のコマンドを入れれば、おそらくすべてのプロセスが止まります。念のため再起動してもhttpdが動かないことも確認します。

sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist

httpdが動いているかどうかを確認するには、以下のコマンドを入れてください。このコマンドで80番や443番ポートをLISTENしているプロセスが見えるはずです。このコマンドで何も出てこなくなれば、OS X ServerのHTTPDのサービスはすべて止まった事になります。

sudo lsof -i | grep httpd

こうしてFMSをセットアップしますが、Web関連のフォルダが大きく変わります。/Library/FileMaker Server/HTTPServer以下に必要なファイルがあります。Webの公開フォルダはHTTPServer/htdocsにあります。ここにファイルを起きますが、httpdプロセスはfmserverアカウントで稼働していることに注意が必要です。_wwwではありません。

設定ファイルは、HTTPServer/conf/httpd.confがまず読み込まれます。設定を変更するには、まずこのファイルから確認しましょう。OS X Serverのよう「全部バーチャルホスト」的な設定ではなく、デフォルトのドキュメントエリアを使います。以下はその設定例です、ほとんど自分のメモみたいなもんです(笑)。赤字は追加記述です。.htaccess等を稼働させるには、AllowOverrideの指定が必要です。PHPはすでに動いていますが、既定のファイルはindex.htmlだけです。なので、DirectoryIndexの指定も行います。もちろん、必要に応じて設定は加えます。

<Directory "${HTTP_ROOT}/htdocs">
     Options All -Indexes -ExecCGI -Includes
     AllowOverride All
     Order allow,deny
     Allow from all
 </Directory>

DirectoryIndex index.php index.html

ここで、設定ファイルを変更したらapachectl gracefulと思いたいところですが、普通にこのコマンドを入れても、OS X ServerのApacheの状況を変えようとするだけで、FMSが起動しているhttpdには適用されません。FMSのhttpdのスタート、ストップ、そして設定の反映は、次のようなコマンドを打ち込みます。

sudo touch /Library/FileMaker\ Server/HTTPServer/start
sudo touch /Library/FileMaker\ Server/HTTPServer/stop
sudo touch /Library/FileMaker\ Server/HTTPServer/graceful

もちろん、フルパスでなくてもかまいません。これらのファイルの修正日を更新するのです。こうすると、/S/L/LaunchDaemonsにあるcom.filemaker.[start|stop|graceful].plistによるファイル修正の監視が行われていて、FMSのhttpdデーモンの処理を行います。これらのlaunchdファイルを見れば分かりますが、/Library/FileMaker Server/HTTPServer/bin/httpdctlというコマンドが用意されていて、このコマンドを経由して、httpdをコントロールするようです。

そういうわけで、設定ファイルを変えてはsudo touch gracefulとやればいいということです。日曜日はOS X ServerとFileMaker Serverのメンテで終わってしまった…。

今年もよろしくお願いします

年末、新年、何かブログにと思いながらも単なる挨拶だけになりました。書く事はいっぱいあるのですが、ほかにもやるべき事がたくさんたまった2014年の新年です。昨年は前半は悪い事ばっかりで、まだ解決していないこともいくつもあるものの、後半はいいことが続き、上向きな感じです。個別に箇条書きにしたいくらいなのですが、余裕のない今は前だけを向いていようと思います。5日の日曜からフル稼働、そして、今年は珍しく大阪での仕事からスタートというところです。たくさんのことが降り掛かっているものの、なんだかどれも先の時間軸が見える感じのいい感じな仕事はじめでした。ビジュアルがないのも寂しいので、2014年正月の瀬戸内海の夕日です。今年もよろしくおねがいします。

IMG_0425

「気付き」という言葉について考えてみた

最近というか、ここ4、5年前から「気付き」という言葉がよく使われます。古い人間として、やや違和感があり、自分ではあまり使わない言葉ですが、やっぱり気持ち悪いと思う人もいるようです。

当然ながら、気付くは動詞、気付きは名詞です。しかしながら、気付きは「気付いた事」という以上に、自分自身がその事柄を所有している意識が強い単語と考えます。つまり、気付いた上でその背景を理解し、その事柄を別のことにも活かせるという意味を示すために使われているのではないでしょうか。しかしながら、気付いて、理解して、解釈してということもみんな動詞です。動詞って単なるプロセス的にとらえられることもよくあります。「早く起きるのは大変です」「起きるのは当たり前だろう」、つまり、起きて会社に行くのは当然というプロセスの中の動作が「早く起きる」ことなのです。一方「早起きは大変です」となるとどうでしょう。やっぱり「当たり前だろう」と思うかもしれませんが、「早く起きること」自体が成果になっているニュアンスが若干あります。うがった見方をすれば、「早起きして遅刻しないで出社できたという成果があった」という心理があるのではないでしょうか。

つまり、何かが起これば「気付く」のは当たり前だし、そういう状況になったら誰でもできるだろう、やるだろうという考えがあります。一方「気付き」というのは、その人が気付き理解したという成果を強調していることなのです。何でも成果を求められる昨今、イメージとして成果っぽい言葉が頻繁に使われるのはよくわかります。

しかしながら、この「気付き」は自分の成果だけでなく、自分が所属する組織に対する貢献を、暗黙に示す言葉でもあると考えます。お店に注文したとき、商品がないとき、「お取り寄せましょうか」と聞かれますが、「お取り置きしましょうか」という言い方もよく言われます。前者は、お客の注文だから仕入れるのは当然というニュアンスもありますが、後者はお店として顧客の要望に応えましたという成果の強調が感じられます。名詞化することで、自分の成果となり、組織の成果となる。そうなれば、言葉は自然に根付き、となるわけです。

さらに、動詞は続きを求めます。「お客様のお言葉に気付きました」「で、何を気付いたの?それでどうしたの?」となります。ところが「お客様のお言葉に気付きがありました」となると、もちろん、それはどうなのと聞きたくなりますが、何となく完結感漂う言い方となり、あまり突っ込めない雰囲気を作っています。よく、「悟る」と「悟り」が引き合いにだされますが、「悟り」と言ってしまえばそれ以上突っ込めません。「気付き」と言ってしまう事で、ある種の遮断、つまり言葉のやり取りの遮断が発生します。何かを報告するときになるべく上司に突っ込まれないようにしたいという気持ちが「気付き」という言葉を引き出すのかもしれません。

気付きという言葉に違和感があるとしたら、そのときのコンテキスト(文脈)において、成果を暗黙的に強調しているからだと考えました。その上で、深堀を暗黙に否認する感覚を聞いた人にもたらします。本来は、気付くことによって、他のことに応用できるわけですが、気付きだけを強調すると、本当に応用しているのかという疑問も湧きます。そして、応用できないのなら、ほんとに気付いているのかという疑問にもつながります。そして、その確認を遮断するのです。少なくとも「気付き」は悪い言葉ではありませんが、その結果、何ができるのか、何ができたのかを同時に伝えることで、違和感はなくなるのではないでしょうか。

計画停電サイトtden.me運営者の意見

計画停電検索サイトtden.me (msyk.net/blackout) 運営者としての見解を記載しておきます。

2011年3月11日に発生した東日本大震災により、電力供給元の福島の原子力発電所が大きな被害を受け、発電できなくなるという事以上に放射能を自然界に放出してしまったという最悪の事態にまでなっていることはみなさんがよくご存知のことです。震災直後より、東京電力では「計画停電」(当初は輪番停電)として、電力供給不足に対処してきました。私の住んでいる地域は何度も計画停電による停電が発生し、うち、何回かは夜の停電でした。もちろん、さまざまな不便はありますが、状況を考えれば仕方ないと考えていました。

計画停電が実際に実際されたのは概ね3月中です。4月以降、電力需要が下がることもあってか停電は実施されていません。しかしながら、夏の電力需要が高まる時期に、停電が起るかもしれないということで、東京電力よりさまざまなアクションがなされています。節電の呼びかけと同時にどうしても供給が足りない場合には計画に従った停電を行うというものです。

こうした東京電力の姿勢について「原子力発電の必要性を暗黙に理解させるための茶番である」といった批判がメディアを中心にしてなされています。「計画停電検索サイト」はそうなると、東京電力のそうしたプロバガンダに協力するものかと思われるかもしれません。

しかしながら、当サイトの管理者として、東京電力の原発プロモーションに協力するものではないことを強く主張します。停電といった今まではほとんど起らなかったことがまさに目の前で起こり、今後も起ろうとしています。避けられないことなのであれば、その情報を提供することによって、事前になるべく知っておくということが非常に重要なことだと考えます。極端に言えば、停電も私たち生活者にとっては一種の災害です。しかしながら、それを知っておく事で、食事の時間をずらすとか、コンピュータを終了しておいたりといったことができるわけです。計画停電に賛同するわけではありません。そうではなく、発生する不便に対する対処をするための情報提供をしたいということです。

原子力発電所については、政府や関係機関は、口を揃えて「安全だ」と言ってきました。すでにそれは嘘だったことが明るみになっています。以前より、私は「安全なら大手町や永田町に原発を作るべきだ」と言ってましたが、今やそれはジョークにもならない状況です。おそらく危険だからという理由で都会から遠く離れたところに作ったのでしょうけども、大事故のために広い範囲に被害が及び、発達した流通網によってその影響は遠方にも及ぶのです。CO2の排出の問題は大きいですが、もっと重要なことは放射能を排出しないことであり、今、放射能が自然界に大量に放出されている事実を認識しなければなりません。

停電は不便ですし、いろいろやっかいないことばかりです。しかしながら、停電が起こりまた取りざたされるということから、放射能を大量に排出するという自然環境のみならず人間社会の破壊が進んでいることを強く意識せざるを得ません。それは人間社会で起った小さな失敗が積み重なったものでもあるわけです。停電によってそのことを多くの人がより強く意識し、どうすれば復旧できるのかということを意識する契機になることを願います。