Stimulus、悪くない

Stimulus: A modest JavaScript framework for the HTML you already have.

2020年末にリリースされた Stimulus 2.0 を試して気づいたことをメモしておく。Stimulus は Rails で有名な Basecamp のメンバーによって開発された生 DOM をベースに、できるだけ template に JS を書かずに動的な DOM の生成、変更を実現するためのライブラリである。

昨今流行りの React, Vue, Angular などの VirtualDOM 系のツールとは根本的に考え方が異なり、今からこれを採用するのはやや申し訳ないというか、正直に言うとよいイメージはなかったし、例えばフロントエンドエンジニアとしてスキルアップしたいぜーという人には合わないと思うが、ただ、どうせサーバサイドの開発が必要で、分業できるほどパワーに余裕のない現場においては VirtualDOM 系よりもかなり高い生産性を維持できると言えそうだ。

少なくとも多能工と多能工が組んでアジリティを確保していこうぜ、という2000年代の空気、Rails誕生前後の空気を再び感じることができる。実際に少ないコードでそこそこのものを高速に開発してオレツエー感を味わえるという意味ではかなりよい選択肢の一つと言えると思う。

StimulusはDOM操作の世界でのよいレール

Stimulusのイメージコード

<div data-controller="counter">
  <span data-counter-target="count"></span>
  <button data-action="click->counter#up">up !</button>
</div>
class CounterController extends Controller {
  static targets = ['count']
  static values = ['count']

  up () {
    this.countValue++
  }

  countValueChagend () {
    this.countTarget.innerText = countValue
  }
}

const app = Application.start()
app.register('counter', CounterController)

簡単に説明すると

  • data-controller で指定した DOM 要素と Controller インスタンスが紐づく1
  • Controller の中で変化を検知できる値として values があり、DOM 側からは data-*-value=<identifier> でアクセスできる
  • Controller 側から操作可能な DOM 要素として targets がある2
  • Controller のメソッドを呼ぶには data-action を利用する
    • event は default のものは省略することができ、この書き方を利用すると event を意識することなくメソッドを呼び出しているように見える

伝統的なDOM操作の世界でのStimulusのメリット

  • DOM の影響範囲を data-* で限定し、そこに効力を発揮する JavaScript を Controller と呼び、関係する処理をこの中に閉じ込めることができる
    • 要素が複数あった場合は自動的に別々の Controller インスタンスと bind されるのでお互いに干渉しない
  • event driven と reactive への習熟という、伝統的なプログラミングスタイルからの飛躍を必要としない
  • DOMContentLoaded 周りの繊細さがない
  • CDN から読み込んだだけで動作する(ES2015 と Proxy に対応しているブラウザが必要)
  • template 側に JS を一切書かずに済むので template 側は副作用込みの行儀悪いものにならない

伝統的なDOM操作コードの問題点とStimulusのアプローチ

残念ながらこの日記にはまとめていないんだけど、上のメリットについては自分も以前からとても頭を悩ませていた。

初歩的な jQuery や VanillaJS で書いたちょっとした装飾や効果、遅延読み込みを実現するコードはほぼ必ずと言っていいほど以下のような問題を抱えている。

  • (event が起きてから DOM の走査を行うので)どこまで影響が広がっているのか想像がつかない
  • やりたいことに名前がついていないので意図が分からない

これは本当に致命的な問題だと思っていた。3

この問題を解消するには 対象と操作を明示する名前を付けたコードの中で、明示した範囲内の DOM だけを操作対象にする しかないと考えていて、自分でそういうツールを書いたりもしていたんだけど4、Stimulus はほぼそのままの回答になっている。

VirtualDOM系ツールを使わないメリット

VirtualDOM系ツールを利用した開発時の課題

VirtualDOM と reactive という考え方は

  • もろもろの「操作」系のコードを省くことでおかしな副作用が途中で混ざり込んでしまう可能性を排除できる
  • event を stream として functional に処理できる

など、より複雑な処理により安全に対応するよい作法である。

しかし逆に、VirtualDOM 系のツールには以下のような問題がある。

  • サーバサイドで組み立てていた HTML の世界に一切歩み寄りがなく、サーバサイドを書いていた手を止めてクライアンドサイドの考え方とツール群に完全に持ち替えないとコードが書けない。完全に分業できる組織ならそれでもよいかもしれないが、特にプロダクトの初期実装時にとても扱いにくく感じる。
  • うまく作用する component を作ろうと思うととても小さいものになり、結果として DOM ツリー全体を構築するためには当初の想像の何倍もの数の component を作らなきゃいけなくなりがち
  • 数多くの component を書いているうちにすべて component だけで解決しなきゃいけないような気になる → 誤った設計を誘発しがち

簡単に言うと VDOM 系は基本的に高くつく。設計ミスも誘発する。そこまでしても速くなるのは DOM の書き換えだけであり、最初の表示は逆に遅くなったりするので、意外と最適化しないと体感速度は改善しない。

VirtualDOM系ツールに対するStimulusのメリット

Stimulus はこれらの問題のすべてを回避できる。改めてまとめ直すと、以下のようにかなり低コストに動的な DOM を利用した体験を実現できる。

  • VDOM 系のツールを動作させるセットアップが一切不要
  • サーバサイドとクライアントサイドの両方をまたぐ処理を書く際に起きる分断がほとんどなく、概ねサーバサイドのコードのような書き味で作れる
  • Stimulus の Controller は VDOM 系の component より少し大きな粒度になるので数をかなり減らせる

もっと細かく調整したり様々なイベントを扱いたいといったニーズはあると思うが、

ツールの大きな持ち替えで手が止まることなくだいたいのケースに対応できる

という実に Rails っぽい考え方でうまくまとまっていると思う。

もちろん、より複雑なロジックやグローバルなステートなどは Controller の守備範囲外だ。その辺りは当然の前提としたうえで考えると、実にニーズナブルでよい解決方法に見える。

そして、実はここが大きいんだけど

  • template 側でのデザインと Controller 側での処理の分業も行いやすい

これ。

VDOM 系のツールを使うと必要以上にデザイナが VDOM 系のツールへの習熟を必要としてしまい、例えばデザイナがツールの習熟度で詰まった際にバックエンドの処理を書いているエンジニアにヘルプがくるとそこでエンジニアの手が止まってしまう。

つまり、

VDOM 系のツールは実はフロントエンドにある程度余裕のあるエンジニアを確保できていないと、デザインの実装に対してもバックエンドの実装に対してもブレーキになり得る

という問題を抱えている。これを解消できる Stimulus というアプローチがとても助かる現場は多いと思う。

Stimulusのデメリット

もちろんデメリットもある。

  • テストしたければ結局フロントエンドのツールチェインの整備は必要
    • そりゃそうだ。もしかしたら頑張って Selenium 経由で console のエラーを拾う、みたいなこともできなくもないかもしれないけど、それはたぶんかなりつらいと思う。
  • Controller のユニットテストは難しい
    • 生 DOM と紐づいてこそ意味があるので、独立したテストは意味を成しにくい。純粋な関数部分のテストはできなくもないが、そもそも Controller に複雑な処理を入れるな、でよいと思う5
    • テストしたければ小さなテスト用の DOM と一緒にセットアップするコードを作る

総じて テストコードを書くモチベーションが下がる と思う。これは凝ったことをし始める時、量が多くなった時に突然牙を剥く可能性がある。

※ もっとも、生 DOM を使ったテストというものはセットアップさえ分かってしまえば書くこと自体はそんなに難しくはない。少なくとも Turbo のように DOM 外の resource へのアクセスが絡まないうちは。(Stimulus の場合は DOM を Controller が mount する部分で工夫が要るけど)

あとこれはデメリットじゃないけど、

VDOM + State Management の開発と異なり、生DOM相手なのでデバッグもブラウザの素の Developer Tools を利用する

ことになる。

参考

  1. DOM 側からは register した名前で紐づける 

  2. どのように操作するかは決まっていない。上の例のように直接書き換えてもいいし、何らかの JavaScript の template を挟んでそこでコンテンツを生成してもよい 

  3. 少なくとも jQuery をやめれば解決するという話ではない。jQuery 的な神オブジェクトを採用するすべての SDK がこの問題を抱えていると言ってよい。 

  4. しかも偶然にも class ベースで書かれている 

  5. 恐らくだが Controller へのアクセス方法を DOM の data-* だけに限定できていて「意図しない呼び出しが行われていない」ことを前提にした設計になっているので、そもそもカジュアルにインスタンスを生成して動かせないようになっていると予想される。 

Coderetreat in Fukui (2013-02-23) に参加してきた!

久しぶりのペアプロイベントだ!と思い、行ってきました。

今回のファシリテータは QuickJUnit / チェンジビジョンの近藤さんでした。

Hiroki Kondo (kompiro) on Twitter

会場スポンサー永和システムマネジメント、ランチスポンサーはチェンジビジョンさんでした。

改めて、ありがとうございました!

準備

日程的にはあとからどんどんきつくなっていったけど、決めたことだし仕方がないっすね。2週間くらい前から仮実装をTDDしてみたりしてました。完成はしなかったけど。

で、準備はですね、やった方がいいですね。なんでかっていうと45分のペアプロはやることがてんこ盛りで結構ハードだからです。この話は後述。

※ 先週の kanazawa.rb meetup #6 で序盤イベントに集中していなかったのは、このイベントの準備と仕事の両方のメドが立っていなかったからでした(笑) すげーつらい時期だった。

簡単にcoderetreatを紹介

Coderetreat is a day-long, intensive practice event, focusing on the fundamentals of software development and design.

  • practice が目的。いろいろやってみよう。
  • 45分1セッションでライフゲームを題材にペアプロする
  • 複数セッションを継続させることはできない。次のセッションでは前のセッションの内容は参照せずに行う。(コードは破棄する)
  • ペアも言語も自由に選択
  • セッションの45分は厳守だが休憩時間は割と自由

Structure of a Coderetreat

この辺読むといろいろ書いてあるので facilitate する場合は熟読すべし :-)

会場の感想

会場は福井の永和システムマネジメントとチェンジビジョンが入っているビルでした。当日は朝7:00の電車に乗った辺りからあれよあれよと雪が舞い始めてうわーなんだこれって感じになりましたが、会場の雰囲気はとてもよかったです。

途中のブレイクで社内見学させてもらいましたが、社員の書いた本が飾ってある棚があって、「小さな書店の技術本のコーナー」くらいの量があるんですよ、これが。しかも「そういやあれもこれも見たことあるぞ、おい」という本ばかり。知ってて買った本もあるけど知らずに買った本も何冊もあって、なんだこの会社はと改めて思ったのでした。

しかもアレ、業務じゃないんですって。信じられない。

イベントの感想

疲れた!(笑)

実は1/3は休んでたんだけど、それにしても疲れました。まぁ、割と疲労のピークには来てましたが、それにしても久しぶりのペアプロイベントはとても疲れました。

でも楽しかった。正しい coderetreat を facilitate するのはちょっと大変そうだけど、この感じを取り入れた何かをするのはとても面白そうだなと思いました。

永和の岡島さんが仰ってましたが、このイベントはコミュニケーションなんですよね。プログラミング言語で、自然言語でコミュニケーションする、それもほぼ45分頭をフル回転させる。そしてより良い何かを目指す。より良い設計かもしれないし、セッション開始時に絞った特別なポイントかもしれないし、一歩でも完成に近づけるための戦術だったりする。

これがむちゃくちゃ面白くて疲れる。

1セッション目はお互いに面識もないし、ちょっとぎこちない感じなんだけど、2セッション目からはやることも見えてるし、各自それぞれの目的でもってこのコミュニケーションが始まります。自分の知らない言語に触れてみたいという思いだったり、さっき思いついたけど達成できなかった実装とか。お互いの人となりは知らないんだけど、少なくともあの空間においてはネタに事欠かない状態なのです。不思議な共有と加速があります。

TDDBCでペアプロしてみた経験はあったけど、業務の中ではやってないし、やるとしても先に目標と時間が読めるものを使って「教える」感じでしか使っていなかったので、この戦闘モードのペアプロというか、こんなのマジで毎日続けてるやつらいるのか?っていうくらい疲れました。45分の縛りが回復を助ける意味にも疲労を倍加させる意味にも働いてるんでしょうね、これ。

あとペアプロやるとソッコーで仲良くなれますね。飲み会よりコストパフォーマンスいいな。車で行けるし、こういうのもアリだな(笑)

個人的な反省

教えてもらう気まんまんで行ったんだけど、そろそろ自分は教えることもできるんだなぁということに気づくことが多かったです。そして周りは型型な人たちばかりだったのに対して自分だけゆるふわだったので「Rubyを教える」感じの時間が長くなってしまって、あれーこういうイベントだったかなぁ?みたいな気持ちになったのはちょっとあります。

でもこれはこれでペアの方にとって新しくて面白い体験だったのかもしれないし、そうであったならよかったなと思います。ペアプロって言っておきながらだいぶ一方的にドライバやり続けててダメじゃんと思ったりもしたけど、今思うとあれはアリっちゃアリなんだろうなぁと。

ただ、それならそれで最速で環境を準備できるようにしておくべきだった。いつもGemfile書いてbundle叩いて…を儀式のようにやっていたんだけど、45分という縛りがつくとこの儀式の時間がない。本当にないんです。ちょっと誤算でした。Eclipseで1クリックで新規プロジェクトを作るのと同等の時間で準備できなきゃいけなかった。反省。

そして使えると言った言語の分、これを用意しておくべし、ということでした。

もう一つは出だしですね。変に聞こうとしすぎてお互いに「うーんどっちでもいいですね」みたいな時間ができてしまうとすぐに残り時間がなくなっちゃう。設計や実装の選択肢をあらかじめ自分の中にもっと用意しておけば、もっと濃くできたんじゃないかなぁという思いがあります。もちろんペア次第ではあるんですけど。

ただ、今振りかえると、そして coderetreat.org の記述を読むと、これを実現するためには言語は揃ってた方がいいっすね。みんな Java はできそうな感じだったし、本当は Java で揃えた方が

Structure of a Coderetreat

をなぞりやすかったんだろうなと思いました。

あとは道具。

Eclipseが使えないと仲良くなれないw 普段のイベントと違ってMac使いも少ないし、みんなIDE使ってるし、これはやっぱ真面目に普段は使わないけど共通言語にする環境は用意しといた方がいいなぁと思いました。Eclipseよりは軽いし、もうちょっとNetBeansと仲良くなっておこう。

※ おまけ。RSpecでshouldをバンバン使ってしまって、ちょっと今後に対して一部悪い印象を与えた可能性あるなぁと思いました。expectの練習が不足してました。

今考えるライフゲームの構成要素

あくまで自分の考える要素です。以下の要素についてそれぞれ考えて設計、実装できるような気がします。

  • 見た目表現
  • 初期状態のセット方法
  • セルのロジック
  • セルの集合の扱い
    • セルの状態(世代管理)
  • 見た目の有限フィールドとゲームの無限フィールド

これを事前に考えておくことができると、どこをどう攻めるか、濃いペアプロができると思います。

取り組み方のポイントのメモ

  • ペアプロと言語と環境
  • TDDでやるか否か
    • TDDはどこでも題材にできるが、そうじゃないやり方は「好きな場所だけ作る」のはやりにくい
  • ペアプロと教えることと参加者の得ること

TDD が coderetreat では推奨されています。自分もできるならやった方がいいと思いますし、今回は参加者にチェンジビジョンの方が混ざってらしたので、そこかしこで TDDBC が自然と展開されて、「うおーTDDすげぇ」みたいな感想が多かったです。なにこの超お得イベント。

その他の会話

  • 今回参加者分かんなかったですね
    • 分かんない方が学生さんが参加しやすいかと思いまして
    • はーなるほど。学生の参加って課題ですよねー。
  • request specってそんないいすかね?
    • stub, mockばかり使ってると実際のデータでうまく動かないごく単純なパターンを見落としたりすることがあったのと、stubが邪魔で変更しにくくなったことがあったので、自分は最近ModelとRequestを中心にやってます。
  • BackboneとかでフロントでJSの比率増えてくるとReuqestよりControllerの方がやりやすいような。
    • それはあるかもしれないっすね。そこまで自分はやったことないんで分かんないですけど。
  • RubyのblockってSmalltalkみたいですね。
    • うぉ。自分はSmalltalk書けないけど、SmalltalkとLispはパクってるらしいですね。
  • RubyはRailsが強くて迷わなくて済むからいいですね。
    • そうですね、そのうえで何をどう実現する、何のためにどういう活動をする、という話に集中できていいと思います。いつまでもツールの話をやらなくていいのは楽っす。
  • 中学校の数学みたいで面白いですね
    • (セッション一つ、0から8の数字を0と1に変換することだけに費やしましたw)
  • JavaScriptてvar付けないとどうなんの?
    • globalにぶちまけちゃうから意図せず壊れる可能性あるよ

今さらRails3メモ - その4: Modelのちょっと変わった基礎 -

Model は奥が深く、また Rails は Fat Model にしろ、の哲学なので長くなりそうということで小出しにする。

ActiveModelをincludeすればなんでもModelに

Rails 2 以前は ActiveRecord と密結合していたけれど、Rails 3 以降で多くの機能が ActiveModel に切り離された。ActiveRecord を使うアプリの場合はあまり関係ないけど、ActiveRecord から切り離されたということは

DBMS 関係なく Model の機能を利用できる

ことを意味する。

Model のクラスメソッドとインスタンス

Model のクラスメソッドには table_name, human_name などがあるが、Model.new したオブジェクトには存在しない。

ましてや Model.all, Model.find の検索結果に至っては Array なので .table_name, .human_name などのメソッドは存在しない。(しばらく悩んでしまった。アホすぎる。)

ということで Model の定義情報はクラスに聞け。

ただし

当たり前だけど ActiveRecord ベースでない Model には table_name などは存在しない。最終的には connection を張って取得してるらしい。

カラム定義は Model.columns に

Model.columns に必要な情報が入っている。inspect のコードを参考にすると

Model.columns.map { |c|
  "#{c.name}, #{c.type}"
}

なんてことをするととりあえず欲しい情報は取れると思う。form field の自動セットとかたぶんできる。

Validation

  • validates がなくて値が不正などの DBMS レベルのエラーの場合はアプリケーションの例外画面がいきなり表示される
  • validates で引っ掛かったら Flash1 でエラーメッセージを出せる

Rails 3 以降は validator は ActiveModel に属すので、それっぽいプロパティと validator を用意すれば DBMS は無関係に Form を作ったりすることもできる。

validates_* なヘルパーはクラスメソッド

これ分かってなくてハマった(情けない)んだけど、validate 関係のメソッドはクラスメソッドなのでそこからインスタンスメソッドは利用できない。要するに

# -*- mode: ruby -*-
class Klass < ActiveRecord::Base
# "undefined ..."
validates_inclusion_of :in => values
# success !
validates_inclusion_of :in => self.values
# cannot be called
def values; end
# can be called
def self.values; end
end
view raw dummy_model.rb hosted with ❤ by GitHub

こういうこと。

validatorの目視チェックを破壊的メソッドで

Ruby on Rails Guides: Active Record Validations and Callbacks

validator がちゃんと動いているかどうかは

The bang versions (e.g. save!) raise an exception if the record is invalid. The non-bang versions don’t: save and update_attributes return false, create and update just return the objects.

ということで ! のついている破壊的メソッドでデータを保存しようとすれば例外が上がって目視しやすい。

  • create!
  • save!
  • update_attributes!

non-bang version(! のついていないメソッド)は false が返るだけだし、rails console で実行していると保存に失敗しても何らかの値がセットされた状態でオブジェクトが表示されるので、

瞬間的に保存に失敗したことを認識しにくい

ので、目視チェックは破壊的メソッドで、と覚えておくと便利。

参考

idはcreateできないのでseed dataを作る際に注意が必要

Model.create( {} )

の際には id を与えることができない。自動で振られてしまうので。ただし

m      = Model.create( {} )
m[:id] = 1
m.save

とすると id を指定できる。

cf. Twitter / Dai Akatsuka: @wtnabe Model.create(:id = …

これの何が問題かというと、id で relation を作る seed data を作っている場合に困る。

fixture の場合はこれは問題にならない。なぜなら ActiveRecord の奥底で直接 INSERT INTO を呼んでいるから。したがってデータの作り方によって

db:fixtures:load はできるけど db:seed はできない

場合がある。

find_by_sql() で複雑なSQLをそのまま書く

Arel は確かにすごいんだけど、複雑な SQL を OO のメソッドチェインだけで実現するのはやはりホネ。素直に SQL を書いた方が簡単なケースはやはり少なからずある。

  • Model.find_by_sql( ) で複雑な SQL をそのまま書ける
    • ちゃんと sanitize というか quote してくれる
  • Model.find_by_sql( [SQL, VAL, VAL] ) で変数への値の埋め込みができる2

この際、join を使った検索結果を console で確認しているとちょっとハマる。console ですぐに目視できる結果は Model 内に定義されている attibute だけなのだ。

しかし実際には join した table の attribute もそのままアクセスできる。これは

Model.find_by_sql().each { |e|
  e[:attr]
}

Model.find_by_sql().first.attributes

で確認できる。ここで確認できる attribute にアクセスするロジックを自由に書ける。

  1. Rails用語のFlashね 

  2. 軽く読んでみたけど DBMS の binding 機構を活かしているかどうかまで読みきれなかった…。 

less 使いが lv を使えるか

長年 less を使っているが、いちばんの理由は

previous page [w] <-> [z] next page

のキーバインドを使っているから。調べたけどこれと同じ操作は lv では実現できないみたい。

man を見てみると

previous page [b] <-> [space] next page

なんてのがある。うーん、[b] が [shift] + [space] ならよかったんだけど。それか

previous page [b] <-> [f] next page

かな。この方がまだ我慢できそうな気がしないでもない。

lv 使いはみんなどのキーバインド使ってるんだろう? 個人的には z/w がいちばん直感的で好きなんだけどね。

高林さん引っ越したのか

いやなブログ: 0xcc.net

RSS を読んでて全然エラーとか出ないから気づかなかった。(つーか上のエントリ見落としてるんだけど。)

なんで分かったのかというと、見慣れないリファラがあったから。

その他の雑酒2を飲んでみた

プレミアムモルツを箱買いした客にこれを試飲でプレゼントするのって、ものすごいセンスだと思うんだけど、もらったものはとりあえず試してみる。

すげー。ビールの風味が全然ない。

果汁系の味のしないチューハイとして飲めばこんなもんかなと思うけど、これで第3のビールって売り方はないだろ。

グループウェアは窮屈だから Wiki にしました

対グループウェアとしての Wiki

グループウェア、ダメ!

そうなんです。

面白くないんです、グループウェアは。なぜなら先にフローが決まってしまうから。と勝手に思ってるけど本当は Notes とかまともなグループウェアは使ったことがない。ただ、なんかお試しできるツールをいくつか触った感じは

窮屈。

DOS 時代のデキの悪いソフトをつかまされたような、手順を縛られたとても窮屈な感じがするのです。これをこうするためにはこっちのこれをこうする必要がある、とか。そんなことしるか!と。こちとらマニュアルなんて一切読まない、直感的に使えないソフトは全部クズだと思っている人間だぜ。<%= fn 'なのに Emacs を使っている :-)'%>

つーことで実は今の環境でも最初にグループウェアの導入を模索してみたんだけど、結局導入したのは PukiWiki のみでした。選んだ理由は、前にも書いたような気がするけど、

  • 当時としてはかなり画期的な valid xhtml を吐く仕様(を目指していた)
  • PHP は使うから、PHP だと将来的にもカスタマイズとかできていいかもと思った<%= fn '結局カスタマイズするとアップグレードしにくいのでほとんどしなくなった' %>
  • 記法が比較的複雑な構文をカバーしているので、まともにドキュメントが書ける
  • BugTrack プラグインがあった
  • PHP だけ動けば使える(RDBMS とかバージョン管理システムとか Pear とか sendmail とか要らない)

かな。

1.3.2 かなんかを使って、当時まだ Windows サーバしかなかったので改行周りの問題がものすごく大量に出たけど頑張っていちいちつぶしていって<%= fn '本家にはほとんどフィードバックしてません。ごめんなさい。' %>、分からんなりにいじるのが面白くて、そうこうしてるうちにあーこれはこういう使い方をするとこういう情報のストックや更新なんかに便利だなというところが見えてくる。Wiki にしてよかったことは「使い方を自分で考えることができた」こと。

メール連動とか便利かもしれないけど、どれだけ便利か分からないのにサーバをセットアップしなきゃいけないのは面倒でいや。目の前に居る人間との共同作業が前提だし、メールは記録として使えるけど基本的にはメッセンジャーと Wiki と face to face のコミュニケーションで足りる。<%= fn 'メッセンジャーは書いたページの URL を飛ばすのに重宝する。「ここに書いたんだけど読んでみてくれ」とすぐ言える。ネットワークの規模がでかくなったら irc にしようかなと模索中。あ。Wiki は他のツールと組み合わせると効果的、というのはこういうところからも感じているんだな。自分は。' %>RDBMS も要らないし、Wiki そのものが考え方を理解するのにちょっと苦労するという問題はあっても、使い始める負荷を比べると、自分にとっては グループウェア >> Wiki だった。

Wiki 信者の戯れ言でしょうか。信者ってつもりはないんだけどな。ページやナビゲーションが簡単にごちゃごちゃしてわけ分からなくなるとか、新たに使ってもらうためにはどうしても記法のとっつきにくさって問題は残るし。でも「高度な自動化が必要なければこんなに便利なものはない」とは思ってるし、「とりあえず Wiki でできないか考える」というクセはついてるかも。よくよく考えると Wiki って全然たいしたことないんだけど、その欲張らなさというか、機能の少なさがかえって自由で気持ちいい、って感じ。

文房具としてコンピュータを使うための Wiki

その前にまず脱線。Web としての Wiki に自分が感じている画期的な点は

  • 存在していないページにリンクが張れる
  • 特別な検索ツールを用意しなくても検索できる

この2点。素朴な HTML 直書きから入った人間の素直な気持ちです。いやほんと、Web としてはこれ以上の意味はないんじゃないかと。応用としてはいろんなよさが出てくるんだけど。

日常の道具としての Wiki に感じるよい点は

  • オープンな技術で実装されているし Web ベースなのでプラットフォームを選ばないことが多い
  • なおかつ LL で実装されているものが多く、準備が楽
  • したがって localhost に実験環境とか自分用の Wiki を用意しやすく、道具を Wiki に一本化しやすい<%= fn '環境が縛られるのはいやだけど道具がバラつくのは邪魔くさくてきらい、というわがままな自分にぴったり。' %>
  • ファイルが添付できるとますます成果を Wiki に集約させやすくてよい
  • Web ベースなので作業する機械とデータの保存場所を分離しやすい
    • 特定のクライアントマシンの中を探さないと必要なデータが出てこない、そしてその人は休んでてどこにあるか分からない、とかいう複数の人間が絡んだ作業のときに陥りやすい事故を簡単に防げる
    • データの保守と機械の保守を分離しやすい。自分の機械が壊れたときの損失を減らしやすい。
  • 検索できる<%= fn 'バイナリデータでも添付してコメントつけとけばすぐ検索できるようになる。もちろん画像についてはアルバムソフトなんかに頼った方が目的の画像に到達しやすいと思うけど、データの 5W1H の一部でも書いてページに貼付けておくだけで、いろんなデータが一気に再利用しやすくなるってことは自分にとってすごく嬉しい。最近でこそ OS がバイナリファイルに対してまで grep の機能を提供したり、さらにインデックスもバックグラウンドで起こして高速に検索できたりするけど、特定の OS の機能によらずにこれが実現できるのがよい。' %>
  • ファイルの管理を意識しなくてよい

ここまでくると Wiki 信者と言われても文句は言えないのかな。でもここに WikiWay の精神はたぶん全然出てきてないと思う。

Perl に疲れた、ってのは噂にも出てこないのか

textfile.org 経由で

プログラミング言語ユーザーの噂

  • ほとんどが言語オタクか日本人。
  • ドキュメントは書かず「ソースがドキュメントだ」とうそぶく。

言語ヲタだから Ruby を使うって噂なんすか。私は「昔は Perl 書いてました」って人が多いと思ってるし、それは定説になってるもんだとばかり。だぁって use strict でいちいち my してたら Perl で書くメリット半減でしょ。余計なことせずにいきなり書けちゃうのが Perl のよさじゃないのかと。で、use strict して my しまくるくらいなら Ruby で書いた方が同じことを実現するための記述量は小さくなると思うし、ちょっとでも OO で書きたいとか思ったらもうそれは雲泥の差でしょう。言語の環境を自由に用意できるのであれば、あとはライブラリの差をどう判断するかってところに落ち着くと思うんだけど、そういうもんじゃないのかな。

あと、ドキュメント重要。でもソースに書いてある。Wiki にも書くけど細かいことは RDoc<%= fn "RDoc は Ruby のコードにドキュメントを埋め込むタイプのもので、http://raa.ruby-lang.org/project/rdoc/ にある。Ruby 1.8 以降標準添付。イメージとしては javadoc, phpdoc を簡単にしたような感じ。いちばん簡単な使い方は class, def の直前にコメントを書いておいて、'rdoc -c CHARSET .' とするとカレントディレクトリ以下のコードをパースして HTML のドキュメントが生成される。これ以上は各自ぐぐるか自分で試すこと。たぶん自分で試すのがいちばん早い。" %> 読め。が、今どきじゃないのかな。

なんかどうもここにある噂は単に作者の生態や有名な言葉が並んでるだけのような。ちなみにその作者まつもと氏は

Re:死にやがれ(/.-j)

ぶっそうなサブジェクトですが、アイディアレベルを含めて10個くらいの言語を思いついたようですな。

Linux か Mac かと思ってた

RSS なんかもこんな感じかも。

なんの話かっつーと Wiki コミュニティが Wiki 万能言い過ぎてねーかって話と、それを受けてたぶん sheepman 氏がいろんなものに当てはまるなーと思って伏せ字にしてみたところ、私は Linux, Mac を思い浮かべました、という話。

ただ、面白がって遊び倒さないといいも悪いも見えてこないってこともあるのよね。面白そうなものに飛びついてハマりつつ適度な距離感を見失わないバランス感覚をいつまでも大事にしたい。と言いつつ del.icio.us も MM も bloglines も mixi も Gmail もやってませんけどねorz

subversion 1.0 source

wakatonoの戯れメモ経由。

まだバイナリは全然できてないみたいだけど、1.0.0 のソースアーカイブが出ました!

来ちゃったか! ほな試すか!

Emacs と半角カナ

生 Emacs 21 で半角カナの入ったファイルを開いたら文字化けというかまともにマルチバイト文字が解釈されてなくてどうしようもなくなってしまう、という現象が起きていたのだが、これが解決した。

/* 生。というのは XEmacs の場合は問題なく読み書きできたから。Mule や Meadow も試していないがきっとそうだろう。 */

要するに文字コードを Emacs に自動判別させずに指定してやればよかった。問題の現象は sjis で半角カナを入れた場合には発生せず、euc-jp の「半角カナ」のときだけ発生し、また terminal に依存しないことから Emacs のコードの解釈の問題だとは早いうちに当たりがついていたんだけど、面倒だったのと、あまり直接的な回答が見当たらなかったので伸ばし伸ばしになっていた。

結論から言うと

  • 編集対象ファイルの中で Emacs に対し文字コードを指定する際の細かいルールが分かっていなかった。
  • 拡張子ごとに文字コードを設定することができるはずだと思ってはいたが、具体的にどういう設定方法になるのか分かっていなかった。

の2点が問題だった。今回、どちらも解決した。

  • -*- 方式は2行目に書いても有効にならなかった。1行目に書いたらちゃんと動作した。
  • 拡張子ごとの設定は (modify-coding-system-alist 'file "ファイル名のパターン" 'コード) で ok だった。

ちっちゃく昇進

することになりました。

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm