石川啄木のTwitterBotを作った
Twitter上で石川啄木の詩を呟くBotをRubyの習作がてら作ってみました。
http://twitter.com/takuboku_
- 仕様
・ときどき(今は/2h)、石川啄木の詩を呟く。
・元データは『一握の砂』『悲しき玩具』の2冊
・Followは返しません。
・Replyへの反応もしません
- 動機
石川啄木の詩があまりにも他人に思えず、またTwitterの風土に馴染みそうと感じていました。
これをTwitter上でちょくちょく読めたら嬉しいな、と思い作りました。
- 製作
Rubyの手習いも兼ねているので、Ruby環境の導入から開始しました。
TwitterのAPIはTwitter4r(Ruby用TwitterAPIライブラリ)を使ったのですが、
最初Windowsでgemを動かすのに難渋、最終的にはMac上で作業をしました。
Macってデフォルトでruby入ってるんですね・・・
元のBookデータを適当にパースしてXML化、ランダムに読み込んで表示させています。
最初は普通に立ち上げっぱなしのデスクトップで走らせればよいかとも思ったのですが、
自由に使えるサーバがあったことを思い出したのでそちらでデーモン化して動かしています。
RubyのWebrickだとデーモン化も3行程度で済みました…。
- 命名
「たくぼっと」と名づけようかとも思いましたが、故人に失礼かな、と思いid:takuboku_、名前:石川啄木になっています。
ただ、だんだん普通のついったったーさんにしか思えない瞬間が増えてきたので変えないとは限りません。
- 所感
元は三行詩の作品なので、そのリズムを殺さないようにどうすればいいのか悩みました。
新聞などで標準となっている\による分かち書きは個人的に目障りに感じてしまって好きでないので
今のところは改行を全角スペースで置き換えることで対処しています。
良いお知恵がありましたらお貸しいただけるとうれしいです。
「TWAINソースが選択できません」の解決
Canonのスキャナ(うちの場合はLiDE40)で「TWAINソースが選択できません」というエラーに時々出くわしていました。
今回本格的に困ったのでいろいろ踏ん張っていたところ、
「悟茶辞苑ッ」さんのところのエントリに救われました。
以下引用です
Canoscan 9950F ドライバの問題:回避方法
以下不具合報告の手短なレポ。システムの環境変数PATHに値を追加するようなアプリケーションが多数インストールされている場合、スキャナドライバが正常に動作しない。
PATHの長さ制限は2,000文字程度だけれど、CanoScanドライバは700文字を超えたあたりで不具合が起きる。
スキャン時には一時的にPATHの値を短くしてやる必要がありそう。
私にはどうもキヤノンがこの問題を深刻なものとして取り扱っているようには思えない。問題を報告して数年が経過したにもかかわらず、この問題は未だに修正されていない(ナレッジベースにも掲載されていない)。それに、どうも9950Fに限らずいろいろなモデルのスキャナで起こるっぽい。
もし(明らかにそれがあるにも関わらず)「rmslantc.dll」が見つからないというエラーメッセージが出て、ドライバを再インストールするよう勧められたなら、このバグのせいだ。
アプリケーションによってはDLLが欠けているとは告げず、単純にスキャナが利用可能でないと報告するかと思う。
役立つ回避方法としては、PATHをシステムのものとユーザ別のもので分けてしまうこと。必須ではない(システム関連ではない)値はユーザ別のPATH変数に入れる。
ユーザ別のPATHは値の内容を損なうことなく、その場で直接編集によって一時的に名前を変更することができる(再ログインが必要 ※訳者注:私の場合、システムのPATHを短くして問題の解決を確認したんだけど、特に再ログインの類も必要なかったです。ただ、スキャナを使うアプリケーションの再起動は必要かも)。
このさらに元の記述はこちら。
PATHを削る、だけで解決するとは思いませんでした。
(XPの場合、PATHをいじるには、「マイコンピュータ」を右クリックー>プロパティー>「詳細設定」タブー>「環境変数」ボタン
ー>「システム環境変数」囲み内の“PATH”を選択して編集でいけます。
どれが必要かわからなければ、とりあえず全部メモ帳あたりにコピーして、設定してスキャン。後で書き込みなおせばよいと思います。)
gochaさま、元記事を書いたreviewerさまありがとうございました。
■
こちらから。
http://mono.kmc.gr.jp/~miz/shippo/
コメントや名前の扱いをどうしようか考え中です。
名前は「サインでええんでは」という声もあるし、でもフォームがあったほうが書きやすいよねという話もある。
コメントについては増田のトラックバックみたいな「コメントもエントリ(絵)」の
シンプルな(枝分かれしない)ものがよいかと思っています。
今回描線部のアルゴリズムを作るに当たって、nitoyonさんのコードを参考にさせていただきました。
http://d.hatena.ne.jp/nitoyon/20071121/uniqlo_grid_line
ありがとうございました。
■
FlexのTimerクラスを使って、ストップウォッチっぽいものをつくっていたけど、このTimerクラスの精度が渋い。
http://www.bit-101.com/blog/?p=910でもガイジンさんが言及しているけど、自分の環境でも1分に3,4秒の狂いが平気で出る。
これは、TimerクラスがTIMERイベントのHandler実行中に、停止してしまう(次のカウントを開始しない)ために起こる。
ので、クラスリファレンスからして
たとえば、SWF ファイルを 10 fps (1 秒あたりのフレーム数)、つまり100 ミリ秒間隔で実行するように設定し、80 ミリ秒でイベントを発生するようにタイマーを設定すると、Flash Player ではおよそ 100 ミリ秒間隔でイベントが実行されます。
と書いてある。
Timerクラスは便利なのですが、実時間と連動するのが必要なタスクには向かないようです。
解決策としては2つが考えられそう。
- リファレンスに素直に従い、Timer(80)なり、適切なミリ秒を設定する。Timerの動作は、Handlerの動作の間“待ってしまう”ため狂いが大きくなる。そのため、Handlerの動作時間を見越してdelayを与えてやればいい。
- Timerクラスの使用は諦めて、Event.ENTER_FRAMEを拾う。
上のガイジンさんもお勧めの方法。具体的にはこんな感じ。
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
…
private function enterFrameHandler(event:Event):void
{
trace("hoge");
}
ただし、Event.ENTER_FRAMEは時間を一切考慮せず、「Flashのフレームの進捗にあわせて」発行されるため、
コンピュータの動作速度等に依存する部分が大きくなる。
また、FlexデフォルトのFPSは24であるため、場合によってはFPSを設定する作業も必要かもしれません。
FPSを変更するためには以下。
stage.frameRate = 60;で、fps=60になるはず。(ただし、表示オブジェクト追加後に呼び出さないとstageからnullが返る。
ので、例えば
今回くらいだと大して困らないけど、Flexでゲームを本格的に作ろうと思った場合、結構問題になってくると思ってメモ。
AdobeがFlexBuilderを無料で
学生、学校関係者限定。
Flexの統合環境「FlexBuilder3」(8万以上)を無料で配ってるので申し込んできました。
http://www.flexregistration.com/
から。
要学生証のスキャンデータ(GIF,PDFで)。
■
Flexをいじっていて、CanvasコンポーネントにSpriteをaddChildしようとしたところ、
以下のような例外が出て怒られてしまいます。
TypeError: Error #1034: 強制型変換に失敗しました。controls::Bezier@8a9c381 を mx.core.IUIComponent に変換できません。
DisplayObjectを継承したSpriteをCanvasにaddChildできそうな気がついしてしまいます。
*1
[http://livedocs.adobe.com/flex/2_jp/langref/mx/core/Container.html#addChild():title=
Canvasクラス(というか、Container以下のクラス)のaddChildメソッド]には以下のようなメモがついています。
メモ :メソッドに対する child 引数は DisplayObject 型として指定されますが、この引数がコンテナの子として追加されるには、IUIComponent インターフェイスを実装する必要があります。すべての Flex コンポーネントがこのインターフェイスを実装します。
IUIComponentには、UIComopnentとしてクラスを扱うためのメソッドやプロパティがまとめられています。
ContainerでaddChildなどのメソッドは一度オーバーライドされており、実質UIComponentクラスを対象としたものになっているというわけです。
Canvasクラスに対してSpriteをaddChildしようとした場合、以下のコードのようにAdapterパターンっぽく
Spriteを一旦UIComponentクラスにaddChildして、その後でこのUIComponentをCanvasにaddChildすればよいようです。
package
{
import flash.display.Sprite;
import mx.core.UIComponent;public class mySprite extends UIComponent
{
private var sprite:Sprite;
public function mySprite()
{
super();
sprite = new Sprite();
}
override protected function createChildren():void
{
super.createChildren();
this.addChild(sprite);
}
.....
}
}
このエントリを書くに当たって、こちらのサイト(日本語訳エンジンを通して)参考にさせていただきました。
ありがとうございました。감사합니다!
「영원의 헤아림」[FLEX] 왜 Sprite는 Canvas에 addChild 안되는 걸까?
http://warkyman.tistory.com/tag/UIComponent
日本語訳
http://j2k.naver.com/j2k.php/japanese/warkyman.tistory.com/tag/UIComponent