続・EmacsでのActionscript開発環境

先日迄の間で構築した環境です。

残り細かい設定を加えたいと思います。


cygwin
既に導入している場合は飛ばしてもいいですが、無い人はあると便利かもしれません。元々、rascutを使うだけならOneClickRubyで十分なんですが、以下の理由でやめました。

  1. cmd.exeは使いたくない
  2. 使い慣れたTeraTermを使いたい
  3. 他のコマンドも使いたくなったw

cygwinここから落とせます。今ならbeta版の1.7でもいいですが、不安な人は安定版でもかまいません。installしたものは

ぐらいでしょうか。あとは依存関係でいろいろ入ってきますが、installerおまかせで十分です。


teraterm
teratermは大昔からあるターミナルエミュレーターですが、現在はオリジナルteratermをベースにしてSSH対応などの改良を加えられたttssh2がいいでしょう。こいつにはcygtermが一緒に入っており楽ちんです。


linum.el
Emacsはモード行にcurrentの行番号を表示することはできますが、エディタなどでよく見かけるソース内に行番号を表示する方法が、デフォルトでは用意されていません。Emacs22以降のrepositoryからcheckoutした最新ソースではデフォルトでlinumが入ってますが、現時点では手動で設定します。

http://stud4.tuwien.ac.at/~e0225855/linum/linum.html

ここから取ってきて、.emacs.elに以下のように設定します

(require 'linum)
(global-linum-mode t)
(setq linum-format "%4d ") ; 4桁分のスペース確保

linum-formatはprintfフォーマット的に書くことで、見た目を整えられます。

EmacsでのActionscript開発環境

普段はFlexBuilderを使っています。Eclipseベースであり、総本山adobeが開発していることもあり、非常に便利で高機能ですしとても助かるのですが、当然Eclipseなので重いです。それでも最近のPCスペックなら大したことないんですけど、ちょっと出先で遊びたい修正したいとか、ノート片手に外で〜、とかの場合大変です。


私は外出する場合はNetbook(AspireOne)を利用していますが、こいつにFlexBuilderはちと荷が重い。さすがに動作が緩慢すぎてストレス溜まります。じゃあエディタは何を使うか…というところで結構悩みました。

ぱっと思いついたのはこのあたりです。e-textEditorとintypeはOSXtextmateクローンといってもいい、snippetや拡張性が強烈な新進気鋭のエディタです。intypeはしばらく開発が止まっているのか、まだアルファ版ですが、e-textEditorはなかなかの完成度です。しかもかなり使いやすい。さすがtextmateを習ってるだけあって、開発用エディタとしては相当なものです。しかも本家textmateのbundleをそのまま利用できるというツワモノです。しかし本家のクローンだからといって日本語対応の弱さまでクローニングしなくても(笑)


FlashDevelopはフリーのIDEで、FlexBuilderを使わないならこれ一択と言っても過言ではないです。ぶっちゃけフリーなんてありえないぐらいの完成度で、シェアでも余裕で購入してるでしょう。私も一時期使ってました。が、いまはIDEではなくエディタでいいので、ここまでのソフトはとりあえず対象外。なにせ画面が狭いので・・・


となると、結局Emacs?(笑)もともとEmacs使ってて、いろいろ環境を用意したけど、やっぱり原点回帰というわけですか。まあ使い慣れている分、安心かな。

最低限、これだけあれば十分です。ほかにもrascatなども欲しいですが、とりあえず後回し。


NTEmacs
WindowsEmacsというとMeadowがありますが、「かなり重くなってしまった&余計なパッケージが多い」という個人的印象からシンプルなNTEmacsをお勧めします。

NTEmacs Project

ここからバイナリパッケージが落とせます。適当に展開して適当にディレクトリに置きます。


actionscript-mode
まず下の3つを揃えます。actionscript-modeは古いcc-modeが必要でしたが、最新版ではそんなこともないみたいです(未検証)。とりあえず念のため古いcc-modeもゲットしておきます。

actionscript-mode.el
as-config.el
cc-mode 5.28

load-pathが通ったところに保存します。as-config.elの先頭にある(require as-profiler)はコメントアウトしておきます。


yasnippet
簡単かつ拡張性が高いことで最近流行り(なのか?)のyasnippetです。これは便利ですよ。

yasnippet project

yasnippetには簡単にinstallできるbundle版と定義ファイルを別分けにしたfull版があります。お手軽なのはbundle版なのですが、定義がlispで1ファイル内に直書きしてあるので、拡張しにくい&デフォルトでactionscript-mode対応が無い。したがってここはfull版を利用します。

じゃあyasnippetactionscript-modeはどこよ?って話ですが、かの有名なSpark Projectで定義ファイルが公開されていますので、それをcheckoutして使います。

svn export http://www.libspark.org/svn/yasnippet/text-mode/actionscript-mode/

あとは.emacs.elで設定してやればOKです。参考までに私の.emacs.elです。上記パッケージは.emacs.dにぶちこんであります。

;;; ロードパス設定
(add-to-list 'load-path "~/.emacs.d")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Action Script
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; via http://blog.pettomato.com/content/site-lisp/.emacs
(defvar running-on-x (eq window-system 'x))
(autoload 'actionscript-mode "actionscript-mode" "Major mode for actionscript." t)
;; Activate actionscript-mode for any files ending in .as
(add-to-list 'auto-mode-alist '("\\.as$" . actionscript-mode))
;; Load our actionscript-mode extensions.
(eval-after-load "actionscript-mode" '(load "as-config"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; yasnippet
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(add-to-list 'load-path "~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
(yas/initialize)
(yas/load-directory "~/.emacs.d/plugins/yasnippet/snippets")

続・EmacsでのActionscript開発環境 - Last Verseに続く

指定月の最終日

Actionscriptで指定した月の最終日を出す場合の手っ取り早いやり方。例えば7月の最終日を出す場合。

var _date:Number = new Date(2009, 6 + 1, 0).getDate();
trace(_date) //=> 31

Dateクラスで月を指定する場合0 => 1月なので、7月だと普通は6を指定します。最終日を確認するには翌月の0日を指定することで前月の最終日(=>つまり7月最終日)が返されます。

Flexのカスタムエフェクト

Flexでカスタムエフェクトを作成する場合、お約束があります。


カスタムエフェクトの作成について


いろいろ書いてありますが要するに以下の2つ、ファクトリクラスとインスタンスクラスを用意します。

カスタムエフェクトを定義するには、ファクトリクラスとインスタンスクラスの 2 つのクラスを作成します。

ファクトリクラスは、インスタンスクラスのオブジェクトを作成し、そのターゲット上でエフェクトを実行します。アプリケーション内でファクトリクラスインスタンスを作成し、ズームサイズやエフェクトの持続時間など、エフェクトを制御するために必要なプロパティをそのインスタンスに設定します。その後、次の例に示すように、ファクトリクラスインスタンスを、対象のコンポーネントのエフェクトトリガに割り当てます。慣例では、ファクトリクラスの名前は Zoom または Fade などのエフェクトの名前になります。

インスタンスクラスは、エフェクトロジックを実装します。エフェクトトリガが実行されるか、ユーザーが play() メソッドを呼び出してエフェクトを起動すると、ファクトリクラスによりインスタンスクラスのオブジェクトが作成され、そのターゲット上でエフェクトが実行されます。エフェクトの再生が終了すると、Flex によりインスタンスオブジェクトが破棄されます。エフェクトの対象となるコンポーネントが複数ある場合には、ファクトリクラスは対象ごとに 1 つずつ複数のインスタンスオブジェクトを作成します。

この2つ、どうやって使うというと、基本的にエフェクトをかけたいコンポーネントに対してファクトリクラスを指定し、ファクトリクラスは指定されたインスタンスクラスを参照する、という流れになります。なので乱暴に言えば

  • ファクトリクラス
    • プロパティの設定などを受け持つクラス
  • インスタンスクラス
    • 実処理を実装するクラス

となるのかな。サンプルを見てみましょう。

package
{
  import mx.effects.IEffectInstance;
  import mx.effects.TweenEffect;

  public class MyEffect extends TweenEffect
  {
    public var angleFrom:Number;
    public var angleTo:Number;

    public function MyEffect(target:Object=null)
    {
      super(target);
      instanceClass = MyEffectInstance; // (1)
    }

    override protected function initInstance(instance:IEffectInstance):void // (2)
    {
      super.initInstance(instance);
      MyEffectInstance(instance).angleFrom = this.angleFrom;
      MyEffectInstance(instance).angleTo = this.angleTo;
      MyEffectInstance(instance).duration = this.duration;
    }	
  }
}

まずファクトリクラスです。ここにエフェクトに対するプロパティを設定できるようにpublicな変数を宣言したりします。(1)でこのファクトリクラスを受け持つインスタンスクラスを登録します。initInstanceはoverrideしてsuper.initInstance(instance)を実行しておきます。その上で設定されたプロパティを渡したりします。

次にインスタンスクラスです。

package
{
  import mx.effects.effectClasses.TweenEffectInstance;

  public class MyEffectInstance extends TweenEffectInstance
  {
    public var angleFrom:Number;
    public var angleTo:Number;

    public function MyEffectInstance(target:Object)
    {
      super(target);
    }

    override public function play():void
    {
      super.play();
      createTween(this, angleFrom, angleTo, duration);
    }

    override public function onTweenUpdate(value:Object):void
    {
      target.rotation = value;
    }

    override public function onTweenEnd(value:Object):void
    {
      super.onTweenEnd(value);
    }
  }
}

インスタンスクラスでは以下の3つのメソッドをoverrideします。

  • play()
  • onTweenUpdate()
  • onTweenEnd()

play()の中でcreateTweenしてプロパティの値を設定してます。非常に簡単ですがカスタムエフェクトの一番簡単な例はこれで動いてしまいます。


さて、実際にこのエフェクトをどうやって使うか?ということになりますがMXML上で使う場合は簡単です。まずファクトリクラスのコンポーネントを登録して、それをエフェクトをかけたいコンポーネントのmouseDownEffectトリガに作成したファクトリクラスを指定してやればOKです。

<local:MyEffect id="test01" angleFrom="0" angleTo="360" duration="10000"/>
<mx:Button label="Click Me" width="100" height="100" mouseDownEffect="{test01}"/>

実際にはActionscript上でコンポーネントのトリガにエフェクトを登録することも可能です。

var _effect:MyEffect = new MyEffect();
var _button:Button = new Button();

_button.setStyle('mouseDownEffect', _effect);

オンラインストレージ

最近はDropboxZumoDriveなどのオンラインストレージがとっても便利ですね。複数のPCで同期や連携する際にはとっても便利ですが、この二つは特に利便性という意味では他のサービスより抜きんでてるかもしれない。

ただ、DropboxとZumoDriveはよく比較されることが多いけど、この二つ、考え方というか基本的な利用形態が異なるので単純な比較にならないと思う。

  • Dropbox
    • 完全同期タイプ
    • 特定フォルダは常にオンラインストレージと同期される
    • ローカルPC主体でストレージは中間補助的な立ち位置
    • フリーだと2GBまで
  • ZumoDrive
    • 非同期タイプ
    • ローカルPCはあくまでもストレージのキャッシュディレクトリ的な立ち位置
    • ファイルアクセスはシームレスだが実態はファイルをOpenした時に初めてストレージからダウンロードされる
    • フリーだと1GBまで

どっちが便利か、というのは使う人の利用形態次第、という感じ?ぶっちゃけどっちも便利なんですが、Dropboxはデスクトップタイプの複数PC間で常に同期をとっておきたい人。ZumoDriveはNetbookやノートPCなど、あくまで完全同期は必要なく、必要な時だけアクセスしたい、ローカルにコピーしたい人向け、ってことかなぁ。

ただ、個人的にはソース管理はMercurialを使ってるのでBitbacketにおまかせですし、それほど大容量なファイルを常時扱うわけでもなく、サブノートがいくつもあるわけではないのでDropboxの方が容量的に便利なのかな。