Maximaの問題

maxima

普通にインストールすると、1+1とか普通の文字を使った式の処理は問題なかったが、数学的(例えばsin(x)とか)な表記の式の処理でwxMaximaは固まってしまう。この問題はjsMath用のTexフォントを入れたPCでは起こらなかった。実際にフリーズしたPCにフォントをインストールすると無事処理可能となった。

jsMath: A Method of Including Mathematics in Web Pages

Download TeX fonts for jsMath

 

それから、保存するときに日本語のファイル名を用いるとバグる。保存は英数字のみで。

BP-ZE排気側カムシャフト流用チューニング

これをロードスターのエンジンBP-ZEは吸気側カムの作用角が233°と小さい。一 方排気側は250°であり、この排気側カムシャフトを吸気側に流用するチューニ ングがある。手元には事故で全損となった以前の愛車から取って来た排気側のカム シャフトをある。これを使って実際に今の愛車に組み込んでみる。 間違いある可能性高し。DIYする場合は自己責任でよろしく。


カムシャフトの役割

往復動内燃機関は構造上、作動空間内でガスを燃焼させるため、サイクル毎 に作動ガスを入れ替える必要がある。4サイクルガソリン機関ではきのこ弁等を 用いて作動空間に給排気の経路を形成する。これらのバルブを駆動させる要素が カムシャフトといわれるもの。このバルブがシリンダヘッド上にあ る形式を"OHV"(Over Head Valve)、バルブを駆動するカムまでもをヘッド上に配 置した形式を"OHC"(Over Head Cam shaft)と呼ぶ。さらに、一本のカムシャフト で吸気弁、排気弁を駆動するものを"SOHC"(Single Over Head Camshaft)、給排 気弁毎に一本のカムシャフトを用いるものを"DOHC"(Double Over Head Camshaft)と呼ぶ。物理的な排気量に対して、実際の吸入空気量は異なるものだ がこれらの比を容積効率という。エンジンの出力は一般的に作動空間内のガス量 に比例するため、この容積効率の向上はエンジン性能に非常に強い相関がある。 容積効率を向上するには、吸入及び排気抵抗の低減や、流体の粘性を利 用した慣性過給等の手法を用いる。吸入排気抵抗の低減は、バルブの面積が一義 的であるが、そのリフト量も重要となる。また、慣性過給を適切に行うためには、吸気及び排 気の両弁をいかに適切なタイミングで動作させるかに依存し、ここにカムシャフ トの重要性がある。

f:id:sin4xe1:20150118103014j:plain
図 カムの一般的形状

カムのプロフィール

一般的なガソリンエンジンに使われるカムは玉子型をしている。卵型のお尻 の部分は完全な円(ベースサークル)であり、この部分ではバルブは押されず、 バルブスプリングに押しあげられ、バルブは完全に閉じ ている。カムシャフトが回転し、作用角と言われる尖っている部分に来たときバル ブは押され、ポートが開く。バルブの移動量をリフトと言い、これは、バルブ卵 形先端と、ベースサークル部分の差となる。

バルブタイミング

バルブの開く動作をロードスターNA8Cのノーマル状態のエンジンを例に説明する。

f:id:sin4xe1:20150118103106g:plain
図 ノーマル状態のBP-ZEのバルブタイミング

  1. 排気側バルブがクランク角BBDC56°(Befor Bottom Dead Center、下死点前)にて開き始める。
  2. 吸気側バルブがBTDC5°(Befor Top Dead Center、上死点前)にて開き始める、この時点では排 気側バルブは閉じきってはいない。
  3. 排気側バルブがATDC14°(After Top Dead Center、上死点後)にて閉じる。
  4. 吸気側バルブがABDC48°(After Bottom Dead Center、下死点後)にて閉じる。

吸気側バルブと排気側バルブが同時に開いている時間があるが、これをバルブオーバーラップ という。

排気側カム流用の机上検討

ノーマルエンジンの吸気側カムの作用角は233°と、この種のスポーツカーと しては狭い。そこで、もう少し作用角の広いカムを入れたくなるのだが、排気側 カムは250°で、これを流用する方法が知られている。ネットを徘徊して調べる と、この場合には、オーバーラップは30°くらいが妥当のようだ。これをどのよ うに実現するかが問題となる。

f:id:sin4xe1:20150118103319g:plain
図 排気側カム流用、オーバーラップ30°
におけるバルブタイミング

オーバーラップを30°とするには、吸気側バルブがBTDC16°で開くようにす れば良い。この場合クランク角センサのある排気側を弄らなくて済む。この状態 でのバルブタイミングは、以下の表のようになる。

 OpenCloseMax.Lift
Ex side 124(BBDC56) 374(ATDC14) 249(BTDC111)
In.side 344(BTDC16) 594(ABDC56) 469(ATDC109)

従って、吸気側は排気側に対して位相角で220°遅れて動いている。クランク に対してカムは半分の速度で回るため、カムの角度としては110°、ただし、バ ルブの挟み角により、既に吸気側は50°進んでいる状態(最大リフトの来るタイ ミングを考えると判りやすい)であるため、これを加えて、160°分遅らせてや ればいい事になる。

今回は、タイミングベルトの山ずらしと、それぞれ120°の位置についてるノッ クピンにより、調整する予定なので、どのような組み合わせがあるか検討してみ る。調整方法は、まず始めにカムスプロケットのEの刻印を真上に向け、その状態よりベルトのコマの位置を 適当な方向にずらして、カムが所定の角度になるようにする。

以下に、検討に使用した図を幾つか示す。

f:id:sin4xe1:20150118103348g:plain
A: 1番ピストン圧縮上死点時における、排気側カムの状態
B: 排気側カムを吸気側に組み込み、オーバーラップを30°とした時の、1番ピストン圧縮上死点におけ る吸気側カムの状態

f:id:sin4xe1:20150118103404g:plain
C1: 吸気側で、ノックピンの位置をカムスプロケットの"E"の位置にあわせて、 "E"を真上にした状態
D1: 吸気側で、ノックピンの位置をカムスプロケットの"I"の位置にあわせて、 "E"を真上にした状態
E1: 吸気側で、ノックピンの位置をカムスプロケットの"Z"の位置にあわせて、 "E"を真上にした状態

f:id:sin4xe1:20150118103409g:plain
上記の3パターンについて、それぞれオーバーラップが30°に近づくようにベルトのコマをずらし た状態。各パターンにおけるコマのずらし方、オーバーラップの値は以下の表

ノックの位置コマをずらす方向コマ数OpenCloseMax.Liftオーバーラップ
E 反時計回り 20 337(BTDC23) 587(ABDC49) 462(ATDC102) 37
I 反時計回り 5 342.2(BTDC17.8) 592.2(ABDC52.2) 467.2(ATDC107.2) 31.8
Z 時計回り 10 347.4(BTDC12.6) 597.4(ABDC57.4) 472.4(ATDC112.4) 26.6

どのバルタイを選択するか悩む所だ。

実際に組み込む

f:id:sin4xe1:20150118104049j:plain

BP-ZEの排気側カムシャフトには、クランク角センサーを接続するためのジョ イントがバルクヘッド側にある。吸気側に利用するためにはこの部分が邪魔なの で切断する必要がある。手で切れないこともなさそうだが、面倒くさいので、会 社に持っていって、会社の工場で切ってきた。切断した位置は、吸気側カム を参考に、カム端面から8mmとした。切断面はバリをとっておいた。

f:id:sin4xe1:20150118104322j:plain

部品の準備も道具もそろったので、週末を利用して、実際の作業を行った。 まずは部品外し。タワーバーは片側を外して上に上げておく。カムカバーを外し、 邪魔なインテークパイプも外す。ウォーターポンププーリーを外すため、オルタネータ を動かしてベルトの張りを緩める。タイミングベルトを緩めるから、ベルトカバー は中間のカバーまで外す。ここまで外して、カム交換に臨む。

まず、クランクを回して、圧縮上死点の位置にする。クランクシャフトプー リーに合いマークがある。バルタイが合っていれば、カムスプロケットの合いマー クが合うはずなので、上死点が上手く出ているか確認できる。 その状態で、タイミングベルトとカムスプロケットに合いマークをつける。と言っ てもスプロケットにはもともと印があるから、その位置に合うマークをベルトに つけるのが趣旨。マーク付けはPOSCAを使うと具合がいい。

f:id:sin4xe1:20150118104338j:plain

交換する排気側カムの方にも、合いマークをつけておく。これは、実際に組 み込んだ場合の位置。イメージは机上検討の時に十分掴んであるので、その通り にすればOK。今回はROMのセッティング等を省いているので、あまりオーバーラッ プを取るのはよろしくなさそうなので、スプロケットのZの位置にノックピンを 合わせて、オーバーラップ26°仕様で行く。この仕様では、スプロケットを時計 回りに10山ずらすので、Eの位置にあるマークから半時計周りの方向に10山の位 置にマークを付けておく。これで、ベルト側の合いマークに合わせれば、時計回 りに10山ずらしたことになる。組み終わると、各マークは一番上に来るはず。組 んだ後、上に示した図(今回の場合はE2)のような位置にカムの向きがあってた ら成功。外した部品をすべて元通りに組み込んで終了。

インプレッション

組んですぐの始動では、HLAとカムの打音が相当出たが、しばらく慣らし運転 している間に消えた。現在はアイドリングも非常にスムーズで音も静か。妙なハ ンチングもない。アクセルを踏み込んでいくと、エンジン回転上昇が多少スムー ズになったかなと言う感じ。プラセボかもしれない。もともと自分の感覚も鈍い ので当てに出来ない。理屈の上からは悪くなりはしないはずだから、まあ良しと いうことで。

リンク集

無断リンクです。

サスペンション交換

ロードスターのオーナーならかなりの人が足回りを交換しているのではない だろうか。しかし、DIYの苦手な人は結構ショップに任せているだろう。サスペ ンションの交換はDIYの手始めとしてはちょうど良いレベルだと思う。コツさえ 掴めば誰でも出来る作業なので、その辺をポイントに記しておく。ただしDIYは自己責任で。


ロードスターの足回り

ロードスターのサスペンション形式は、典型的なダブルウィッシュボーン形 式で、F1でも使われる、スポーツカーとしてはごくありふれた形式だ。調整範囲が 広いので、いじればかなり楽しめるらしい。ノーマルの乗り心地は、市販車とし てはかなり硬く決して良い物じゃない。S-Specialはもっと悪いくてきつい段差ではリアがどたばた する。それでも、峠道とかでコーナリングを楽しむのには十分な性能があると思 うし、自分くらいのペースで走るには十分楽しめる。ノーマルの問題は、フェンダー とタイヤの隙間がめちゃくちゃ広いこと。やっぱり落としたほうがカッコいいのだw というわけで、ちゃっちゃと交換する。

フロントサスの分解

分解の方法

ロードスターのフロントのサスの分解方法としては、2種類が知られてるよう だ。一つ目は、ナックルのボールジョイントを外す方法。もう一つは、ロアーアー ムの隠しボルトを外す方法。前者は、一般にはボールジョイントプラーというちょ っと特殊な工具が必要とされ、後者は、そういった物が必要でないため、こっち の方法をとる人もかなりいると思う。自分としては、アライメントの狂いも少な いと思うので、もっぱら前者でやってる。このとき、ボールジョイントプラーは 使わずに、Fireのページで 説明されてる、 ダブルハンマーを使う方法を用いる。慣れると楽。多少近所迷惑ではあるが。

どこを外すか

ロードスターのフロントサスを分解するときは、以下の部分を外す。

  • アッパーマウントのナット(14mm)
  • ロアーアームのボルト、ナット(17mm)
  • スタビライザーリンクのボルト、ナット(14mm)
  • ナックルのボールジョイント(17mm)

f:id:sin4xe1:20150118102556j:plainf:id:sin4xe1:20150118102648j:plain

それぞれ、それなりの硬さで締結されてあるので、硬い場合は、CRC556を使 うとか、ブレーカーバーにパイプをかますとかして下さい。ちなみに今回の交換 では、snap-onのブレーカーバーだけで全部緩みました。

# 以前の車で初めてばらした時には、どこか海外製のブレーカーバーを使っ たのだけど、パイプかまして使ってたら、壊れました。snap-onは良さがわかる w

サスペンションを取り出す

サス交換でいつも迷うのが、全部ボルトを外して、自由になったサスペンショ ンをどうやって取り出すかだ。ちょっと知恵の輪チックで、上手くやらないとな かなか外に出てこない。この文を書こうと思ったのも、これを忘れないため。

  1. まず、サスペンションを自体はボディから離さずに、ロアーアームを下に押し下げ、 ショックの下端をロアーアームからはずす。
  2. ショックの下端を奥側に持っていくようにして、サスを降ろしていく。
  3. アッパーアームを下げながら、ホイールハウス内でアッパーマウントを手前側に持ってくる。
  4. 最後にさらにアッパーアームを下げ、ホイールハウス内からサスを取り出す。

コツとしては、

  • ロアーアームとショックを繋ぐブラケットが外れにくい場合は、アッパー マウントのナットを全部外さずに、サスをボディに引っ掛けておいて、足 で、ハブを踏みつけるように押すと簡単に外れる。
  • 2,3の動作は同時に行うので、ここでも足を使う。両手でサスの上下を持ち、 足でハブを下に押しながら、サスを動かすようにする。

以上で、フロントのサスは取り外せました。

リアサスの分解

どこを外すか

ロードスターのフロントサスを分解するときは、以下の部分を外す。

  • アッパーマウントのナット(14mm)
  • ロアーアームのボルト(17mm)
  • スタビライザーリンクのボルト(14mm)

適当な写真が無かったので写真は無し。

リアの場合はフロントと違い、ボールジョイントを外すようなちょっと特殊 な作業は無い。しかしながら、その分簡単かというとそうでもない。困難な点と しては以下のような事がある。

  • アッパーマウントがトランクの奥の方に有り、特に左は燃料ホースなどの 障害物があり、作業スペースが狭い。
  • アームの動作量と、サスペンション取付部の形状より、ホイールハウスか らサスを取り出す際により困難がある。

一点目はひたすら狭いスペースで作業するしかない。40~50mm程度のエクステ ンションをラチェットにかますと少し作業性が上がる。アッパーマウントのナットを 落とすと、取り出すのは非常に困難。2点目は、サスを降ろしていく ときに、フロントとは違いショックの下端を手前に持ってくること。 アッパーマウントの接続部はフロントとは異なりホイールハウス側に筒が伸びているので 奥に持っていくと動きがとれず、ロアーアームとの間にサスがはまり込んで、にっちもさっちも 行かなくなる。自分がやる場合は、

  1. サスを降ろさずに、足でロアーアームを押し下げて、ショックの下端をブラケットか らはずす。
  2. さらにロアーアームを押し下げ、アッパーマウントのボルトが取り付け穴からはずれ自由に なったところで、ショック下端が車体後方に行く様に全体を下ろしていく。

というような感じです。

リンク

無断リンクです。

MS Excelでマクロを使う

Microsoft Excel でマクロを使うことができると処理の幅が 大きく広がる。しかしながら、マクロはVBA(Visual Basic for Applications)というプログラム言語 で書かれ、ある程度のプログラミングの知識が必要となることから使用を敬 遠してしまうことも多い。実際には Visual Vasic で個別のアプリケーションを作成するような 複雑な知識は必要ではなく、単にセルからの値の取得、セルへの値の入力さえできれば、後は 通常のBASIC言語と同様に扱える場合が多い。そういった用途の極簡単な使い方の昔書いたメモ。


Visual Basic Editorの起動

Excel上でマクロを使うにはまず Visual Basic Editor を立ち上げる必要がある。 Visual Basic Editor は、メニューバーから、“ツール(T)”→“マクロ(M)”→“ Visual Basic Editor(V)” を選択することで起動する。(起動画面)

Visual Basic Editorの起動後まず標準モジュールの追加を行う。メニューバーから、 “挿入(I)”→“標準モジュール(M)”で追加できる。これを行うと、プロジェクエクスプローラー上に “標準モジュール”が追加され、エディターペインにModule1という名前の標準モジュール ウィンドウが現れる。この標準モジュールウィンドウ上にプログラムを書いていく。(モジュールの追加)


プログラムの基本

VBAにおける、制御構造等は、一般的なBASICのものと大きな違いは無い。ここではVisual Basic特有の 概念に重きをおいて、少なくともこれだけ知っていればというものについてのみ述べる。その他の詳細に ついては、付属のヘルプや、専門書を読むと良い。

変数の型

Visal Basicには変数の型という概念がある。変数をどのような値として使うかによって 型を適当に選ぶことによって、色々なメリットがあるが、ここでは詳しく述べない。別に型を 用いなくても十分にプログラミング可能なのだが、型指定が必要なときには、特に意識 しないのであればVariant型を選択しておけば間違いは無い。

Subプロシージャ

Sub プロシージャは、Visual Basic の一連のステートメントの集合 からなるプログラム上の処理単位。Subステートメントで開始され End Sub ステートメントによ り終了する。 Sub プロシージャは、処理を実行するだけで値は返さない。Sub プロシージャは 引数を取得できる。 Sub プロシージャが引数を持たない場合、その Sub ステートメントには空のかっこを指定する必要 がある。

引数を持たないSubプロシージャの例

Sub test()
  …
  (一連の処理)
  …
End Sub

引数を持つSubプロシージャの例

Sub test(a)
  …
    b = a
  (一連の処理)
  …
End Sub

Subプロシージャは他のSubプロシージャを呼び出すことができる。プログラム中の一連の処理 毎にSubプロシージャに分離することにより、プログラムの見通しが良くなり、再利用性も上がる。

Function プロシージャ

Function プロシージャは、いわゆる関数を記述するのに用いる。Sub プロシージャと異なるのは、 戻り値を持つことである。呼び出し側のプロシージャでは、その戻り値を使うことができる。戻り値 は、Functionプロシージャの名前に、戻り値の値を代入することで指定できる。

Functionプロシージャの例

Sub test()
    a = 10
    b = test1(a)
    MsgBox (b)
End Sub

Public Function test1(a)
    test1 = a + 10
End Function

この例では、Subプロシージャ"test" からFunctionプロシージャ "test1" を呼び出し、その戻り値 をMsgBox関数を用いて表示させている。Functionプロシージャ"test1"は、引数aに10を足した数を戻す という単純なものである。

組み込み関数

VBAには、多くの組み込み関数が用意されている。特に、数学関数と文字列処理関数などは使う場 面も多いので、どのようなものがあるか知っているだけでもいいので一通り目を通しておくと良い。


Excelとマクロとのやり取り

上記までの説明で、Subプロシージャによる構造化と、Functionプロシージャを用いた関数の 使用が出きれば、それだけでそれなりのプログラムは書ける。しかしながら、データの入力と 結果の出力が出来なければ困る。ここでは、ExcelVBAを使うことを想定しているので、Excel のセルをデータの入力と結果の出力に使うこととし、その方法の概略を述べる。

セルからの値の取得、セルへの値の入力

セルから値を取得するには、取得するセルを指定し、そのセルの"value"プロパティの値を参照する。 また、セルへ値を入力する場合は、入力したいセルを指定し、そのセルの"value"プロパティに値を代 入する。

セルの指定法:A1形式

A1 形式を用いて、セルとやり取りするには以下のような記述をする。

Sub GetData()
    …
    '値の取得
    hoge = Workbooks("Book1").Sheets("Sheet1").Range("A1").value
    '値の代入
    Workbooks("Book1").Sheets("Sheet1").Range("A2").value = hoge + 10
    …
End Sub 

この例では変数"hoge"に、"Book1"のワークシート"Sheet1"のセル"A1"の値が代入される。 また、"Book1"のワークシート"Sheet1"のセル"A2"に、hoge + 10の値が代入される。

セルの指定法:インデックス番号

インデックス番号を用いて、セルと値をやり取りするには以下のような記述をする。

Sub GetData()
    …
    hoge = Worksheets("Sheet1").Cells(6, 1).Value
    …
End Sub

この例では変数"hoge"に、現在のブックのワークシート"Sheet1"のセル"A1"の値が代入される。 また、インデックス番号には変数を指定できるので、次の使用例のようにループを使ってセル範囲 の各セルへの操作を行うこともできる。

Sub CycleThrough()
    Dim counter As Integer
    For counter = 1 To 20
        Worksheets("Sheet1").Cells(counter, 3).Value = counter
    Next counter
End Sub

用語集

ステートメント
コード内で任意の操作、宣言、および定義を行うための、完結した構文を持つ最小単位。
  • 通常は、1 行に 1 つのステートメントを記述する。
  • ステートメント同士をコロン (:) で区切ると、1 行に複数ステートメントを 記述することができる。
  • 行継続文字であるスペースとアンダスコアの組み合わせ ( _) を使うと、 1 つの論理行を 2 行以上の物理行に分けて記述することができる。
引数
プログラムコードが関数やサブルーチンを呼び出すときに相手に渡す値。呼び出された側では、 この引数に応じて(引数を用いて)処理を行なう。

関数定義の書き方

この文章は Programming in Emacs Lisp の中から、個人的に重要と思われたポイントを抜き出してまとめた物です。 従って内容は、これを超えるものではありません。さらに詳細な説明については、上記ページを読ま れることをお勧めします。

[back]


特殊形式 `defun'

関数定義は `defun' という単語に続けて、次のような最大五つの部分を加えたものである。

  1. 関数定義が付けられるシンボルの名前。
  2. 関数に渡される引数のリスト。もし一つも引数をつけない場合、ここは空リスト `()' にする。
  3. 関数を説明する文章。(技術的には省略可能であるが、書くことが強く望まれている。)
  4. 省略可能。この関数をインタラクティブにする、つまり `M-x' に続けて関数名をタイプするか、 適当なキーないしはキーコードをタイプすることで使うことが出来るようにするためのS式を書く。
  5. 計算機に何をすべきかを命令するコードを書く。即ち、関数定義の本体。

関数定義の例:

(defun multiply-by-seven (number)
    "Multiply NUMBER by seven."
    (* 7 number))

引数リストの中で使われる名前は、その特定の定義の中だけでしか使われないプライベートなものであるため、 どんな名前でも選ぶことが出来る。

`apropos' のような幾つかのコマンドは複数行に渡って書かれた説明文の文字列のうちの最初の一行だけ しか表示しないので、説明文字列の最初の一行は完結した一つの文にすべき。

`C-h f' (`describe-function') を使ったときに変な表示のされかたをするので、二行目も書く 場合はこれをインデントすべきではない。

関数定義のインストール

関数定義を評価することで、関数がEmacs を終了するまでインストールされる。古い関数定義を新しいバージョンに 置き換えるには、関数定義を書き直し、もう一度評価すれば良い。

関数をインタラクティブにする

インタラクティブな関数はユーザーが `M-x' に続けて関数の名前をタイプする、あるいは、その関数にバインドした キーをタイプすることで呼び出すことが出来る。関数をインタラクティブなものにするには、特殊形式 `interactive' で始まるリストを説明文字列のすぐ後に置く。

インタラクティブな関数の例:

(defun multiply-by-seven (number) ; インタラクティブバージョン
  "Multiply NUMBER by seven."
  (interactive "p")
  (message "The result is %d" (* 7 number)))

インタラクティブな関数の呼び出し方

  1. まず渡されるべき数を含む前置引数をタイプする。ついで `M-x' と関数名 をタイプする、例えば `C-u 3 M-x forward-sentence'、とする。
  2. あるいは、その関数にバインドされたキーないしはキーコードをタイプす る。例えば `C-u 3 M-e'。

`interactive' の他のオプション

"p" `interactive' の引数として `"p"'を使う場合、`C-u' に続けて数をタイプする か、`Meta' キーに続けて数をタイプすることにより、このコマンドに引数として数 を渡すことが出来る。
r `r' という文字の場合、Emacs はその関数にその時のリージョンの最初 と最後の位置 (その時のポイントとマークの値) を二つの別々の引数として渡す。
B `B' であれば、ミニバッファにプロンプトを出して、バッファの名前の入 力を促し、入力された値を関数に渡す。プロンプトには `B' に続く値が 使われる。例えば、`"BAppend to buffer: "' と記述する。
b 現在存在するバッファ。
f 現在存在するファイル。

関数に二つ以上の引数を渡したい場合、`interactive' に続けて複数の文字列を 付け加えることで、各々の引数に情報を渡すことが出来る。この場合その情報は、 各々の引数に `interactive' に書いたのと同じ順序で渡される。例えば `"BAppend to buffer: "' に続けて `\n' と `r' を書くことで、Emacs はプロンプトでバッファ 名を要求すると同時にポイントとマークの値もその関数に渡す。以下この場合の関数の形式:

(defun 関数名 (buffer start end)
  "説明文字列..."
  (interactive "BAppend to buffer: \nr")
  関数の本体...)

上に挙げたような特定の文字による引数の与え方が目的に合わない場合、独自の引数をリストとして `interactive' に渡すことも出来る。

コードをずっとインストールしておくには

関数定義のコードを`.emacs'の中に書きことにより、Emacs を起動した時にこの`.emacs'が自動的に評価され、 その中に書かれた全ての関数がインストールされる。

また、インストールしたい関数の定義を一つのファイル、もしくは関数ごとに複数のファイルに書いておき、 `load' という関数を使って Emacs にそれを評価させてそれらの関数をイン ストールする。サイト全体でそのコードを使いたい場合は、普通はその関数を`site-init.el' 呼ばれるファイルに書いておく。

`let'

`let'はその `let' 式の外にある同じ名前の変数からは隔離されている変数、 即ち、"ローカル変数" ("local variable") と呼ばれるものを発生させる。

`let' は一度に複数の変数を発生させることが出来、各々の変数に初期値(特に指定しなければ`nil')を設定する。

`let' 式の構成部分

`let' というS式は三つの部分からなるリストである。各々、

  1. シンボル `let'
  2. "変数リスト" ("varlist")
    • 単独のシンボル:初期値には `nil' が設定される。
    • 最初の要素がシンボルであるような二つの要素からなるリスト: 二番目の要素を評価した時に返される値が、初期値として一番目のシンボルに設定される。
  3. 大抵、一つないしは複数のリストからなる`let' 式の本体

`let' 式の例

次のS式は二つの変数 `zebra' と `tiger' を発生させ、それに対して初期値を与えている。 `let' 式の本体は関数 `message' を呼び出すリストである。

(let ((zebra 'stripes)
      (tiger 'fierce))
      (message "One kind of animal has %s and another is %s."
          zebra tiger))

特殊形式 `if'

特殊形式 `if'は計算機になんらかの判断をさせる時に使われる。

特殊形式 `if'は、最初の要素に`if' を、二番目においてテスト部分、三番目に実行部分の三つの要素をもつリストである。 普通`if' 式が書かれる場合、真か偽かのテストは、`if' と同じ行に書かれ、テストが真であった場合に実行される "then-part" は二行目以降に書かれる。

例:

(if (> 5 4) ; if-part
    (message "5 is greater than 4!"))  ; then-part

真偽テスト (true-or-false-test) の部分は List インタプリタにより評価されるS式である。

If--then--else 式

`if' 式は、オプションとして "else-part" と呼ばれる、真偽テストが偽を返した場合のための、三番目の要素を持つことが出来る。

Lisp のコードを書く場合、else-part は新しく改行してから then-part よりは少ないインデントで書き始める。

例:

(if (> 4 5) ; if-part
    (message "5 is greater than 4!")  ; then-part
  (message "4 is not greater than 5!")) ; else-part

Lisp における真と偽

真であるか否かテストされるS式は、評価した結果が `nil' 以外の値であれば "true" と判断される。 Lisp ではシンボル `nil' は「空リスト」と「偽」の二つの意味を持つ。Lisp にとっては、`()' と `nil' は全く同じものである。 もしテストで真を返すような適当な値が見つからなければ、Lisp インタプリタは真を表わすためにシンボル `t' を返す。

例:

(> 5 4)

その他の関数

`equal' `eq'
二つのオブジェクトが同じであるかどうかをテストする。`equal' の方は、 両者が同じ構造と中身を持ちさえすれば、真を返す。一方、`eq' の方は、 引数が両方とも実際に同じオブジェクトである時のみ真を返す。

List 処理

この文章は Programming in Emacs Lisp の中から、個人的に重要と思われたポイントを抜き出してまとめた物です。 従って内容は、これを超えるものではありません。さらに詳細な説明については、上記ページを読ま れることをお勧めします。

[back]


Listとは

Lisp のプログラムはリストもしくは単一のアトム からなるS式で出来ている。リストは0以上のアトムもしくはリストからなる。これらは空白文字で区切 られており、括弧で囲まれている。リストの中身は空であっても良い。

Lisp の中では、データとプログラムの両方が同じ様に表現される。

リストの例

'(this list has (a list inside of it))

このリストの構成要素は、`this', `list', `has', という単語と、`(a list inside of it)' という リストである。内部にある方のリストは、`a', `list', `inside', `of', `it' という単語からなってい る。

Lisp のアトム

アトムは幾つかの文字からなるシンボルである。例えば

  • `forward-paragraph'
  • 一つの文字からなる `+'
  • 二重引用符に両側を挟まれた文字列からなる文字列
  • 数値

リストの中では各々のアトムは互いに空白で区切られている。また括弧のすぐ 隣りに位置することが出来る。中に何も入っていないリストというのは `()' であるが、これは "空リスト"("null list") と呼ばれる。アトムやリストを表示したものは、 "symbolic-expression", もしくはもっと簡単に "S式"と呼ばれる。二つの二重引用符で挟まれたテキストはアトムである。この種のアトムは "文字列" ("string")と呼ばれる。

GNU Emacs によるリストのタイプの支援

リージョン内のコードをきちんとインデントしてくれるコマンドは、`M-C-\' にバインドされている。

シンボル

Lisp では、ある命令セットには幾つかの名前が付随している。一つのシンボルは、一度にただ一つの 関数定義しか持つことが出来ない。 Lisp の中では、 シンボルは、関数定義を持つことが出来るのと同様に、ある値を持つことが出来る。

通常、関数が属する Emacs のパートが識別出来るような シンボルの名前を付け方をする。例えばTexinfo を扱うための関数の名前は全て `texinfo-' で始まる。

プログラムの実行(評価)

Lisp インタプリタがあるS式を処理している時、その動作は "評価"("evaluation") と呼ばれ、以下のように動作する。

  1. list の頭に、引用符が付いているか見る。
  2. もし付いていれば、単にそのリストを我々に渡す。
  3. 一方、付いていない場合はリストの先頭の要素を見に行き、それが関数の定義を持っているかどうかを調べる。
  4. 定義されている場合はその定義にある命令を実行する。
  5. そうでなければエラーメッセージを表示する。

インタプリタは値を返すと同時に、カーソルを動かしたり、ファイルをコピーしたりといった他の動作 も行う。このような動作は、"副作用" ("side effect") と呼ばれる。

引用符 “`” があると Lisp インタプリタはその後に続くS式を書かれたままの形で返し、引用符が 無い場合のように評価したりはしない。リストの頭に引用符が付いていない場合は、計算機が従うべき命 令になる。(Lisp ではこれらの命令は 関数(*function*) と呼ばれる。)

引用符が付いておらず、括弧に囲まれてもいない単独のシンボルを、Lisp インタプリタ変数("variable") として評価しようとする。

幾つかの"特殊形式" ("special form") と呼ばれる関数はその特殊性のために普通のやり方ではうまく 働かない。

Lisp インタプリタは常に一番内部のリストから処理していく。それ以外の場合は、インタプリタは左か ら右へS式を一つずつ処理していく。

数値は評価されるとそれ自身を返し、二重引用符で挟まれた文字列を評価した時もそれ自身を返す。シ ンボルそのものを評価すると、その値が返される。

emacs上では、カーソルを次のリストの右側の括弧のすぐ後に持ってきて、`C-x C-e' とタイプしてリス トを評価することが出来る。

内部のリストの評価

外側のリストが評価される時は、内部のリストを評価した時に返った値が情報として用いられる。Lisp の中では、数字を評価した場合、その値自身が返され、シンボルを先頭に持つリストの直後でS式を評価 したなら、返された値はその名前に付随する関数の定義の中の命令を計算機が実行した結果が返ってくる。

バイトコンパイル

Lisp インタプリタは人間が読めるコードとバイトコンパイル("byte compile") されたコードの二つの種類の物を解釈出来る。バイトコンパイルされたコードは我々が読めるコードよりも 速く走らせることが出来る。人間が読めるコードをバイトコンパイルされたコードに変換することも出来る。 これは `byte-compile-file' 等の、コンパイルコマンドを走らせることによって行う。

関数

関数とは計算機が従うべき命令の集まりのことである。Lispでは、頭に引用符が付いていないリストはあ る命令を実行する。これらの命令を関数(*function*)と呼ぶ。全ての関数は C 言語で書かれた少数の "プリミティブ" ("primitive")な関数を除いて、別の関数を使って定義されている。Emacs Lisp のコードを 書く場合、C で書かれた関数を使う場合とEmacs Lisp で書かれた関数を使う場合とで区別をつける必要は全 くない。

引数

Lisp の中では関数に対する引数は関数に続くアトム もしくはリストである。これらのアトムやリストを評価して 返された値が関数に渡されることになる。異なる関数は異なる数の引数を取り得る。また、全く引数を 取らない関数もある。

引数は評価された時に値を返すシンボル、即ち変数の値やリストであることも可能。例えば、

(+ 2 fill-column)

可変な数の引数をとることも出来る。例えば `concat', `+', `*' といった幾つかの関数では引数の数は 固定されていない。

関数に渡されるデータの型はその関数がどんな種類の情報を必要としているかによる。以下に例を示す。

  • concat:二つ以上のテキストの文字列を連結ないしは合成して一つの文字列を作る関数。この場合の引数は文字列。
    (concat "abc" "def")
  • substring:文字列である最初の引数の部分文字列を返す関数。引数として文字列と数値の両方を取る。
    (substring "The quick brown fox jumped." 16 19)

関数 `message'

`message' という関数はユーザにメッセージを送るものもで、メッセージをエコー領域に表示する。 引数の数は固定されていない。

例:二重引用符に狭まれた文字列全体が一つの引数になっており、その全体が表示される。

(message "This message appears in the echo area!")

%s' が二重引用符に挟まれた文字文字列に入っていたとしたら、関数 `message' は文字列に続く二番目 の引数を評価し、その結果を `%s' のある所に代入して表示する。値を10進数として表示するには、`%d' と いう文字列を使う。もし一つ以上の`%s'ないしは`%d'が二重引用符で狭まれた文字列の中にあったとすると、 最初の `%s' の位置にはその文字列に続く最初の引数の値が表示され、二番目の`%s' の位置には二番目の 引数の値が表示され... という具合になる。

変数

Lisp の中では、シンボルは、 関数定義を持つことが出来るのと同様に、ある値 を持つことが出来る。値としてのシンボルを"変数"("variable")と呼ぶ。

関数定義
計算機が従うべき命令の集まり
数値とか名前のように、何か変化し得るもの

シンボルや数値、リスト文字列等、どんな LispS式もシンボルの値になり得る。

`set' もしくは `setq'という関数を使うことで変数に値を格納することが出来る。別の方法として、 `let' を使うことでも変数に値を格納することが出来る。

`set' の利用

以下のS式を評価する。

(set 'flowers '(rose violet daisy buttercup))

すると、`(rose violet daisy buttercup)' というリストがエコー領域に返され、副作用としてシン ボル `flowers' が、このリストにバインドされる。`set' を利用する時は、`set' の引数には、それら を評価しようとする場合を除いて、必ず引用符を付ける必要がある

`setq' の利用

特殊形式 `setq'は、`set' と引用符付きの第一引数の組み合わせという極めてよく使われるものに、 名前を付けたものである。第一引数に自動的に引用符を付ける以外、`set' とほぼ同じである。`setq' は、一つのS式の中で複数の異なる変数に対して各々に異なる値をセットすることが出来る

使用例:

  • `setq' を使って `carnivores' という変数に `'(lion tiger leopard)' という リストをセットする:
    (setq carnivores '(lion tiger leopard))
  • 異なる変数の各々に異なる値をセットする:
    (setq trees '(pine fir oak maple) herbivores '(gazelle antelope zebra))

`set' や `setq' は、あるシンボルを特定のリストへの*ポイント*にする働きをするという捉え方もできる。

カウント

`setq' をカウンタとして利用する方法:

(setq counter 0)                ; イニシャライザ
(setq counter (+ counter 1))    ; インクリメンタ
counter                         ; カウンタ

イニシャライザでカウンタに0をセットし、次に二番目のインクリメンタのS式 `(setq counter (+ counter 1))' を評価すると、カウンタは一つ増える。その後も二番目のS式を評価するごとに値は増えていく。

シーケンス:

  1. `counter'の評価、戻り値はそのときの値。
  2. 1が評価、戻り値は1。
  3. `counter'の戻り値と1が引数として+に渡され、`(+ counter 1)'が評価される。戻り値は`counter'と1の和。
  4. `(+ counter 1)'の戻り値が引数として`setq'に渡され、カウンタに新しい値が設定される