2008年7月2日
#
前回はSQL Serverでその前がOracleだったので、ぢゃあ次はLINQってことで試してみました。
LINQの場合(というかC# 3.0の場合)は、Aggregateメソッドとラムダ式でうにゃうにゃっと書けば結構できてしまうので、細かいとこは省いてしまいます。
基本
基本は以下のラムダ式があればほぼ問題無いみたいです。(表現が間違っていたらごめんなさい&指摘して下さい)
| (TAccumulate, TSource) => 処理 |
ということで、実際に集計処理をしてみましょう。
集計処理
サンプルでは適当な家族(family)の匿名型を利用して、性別ごとに家族の名前をカンマ区切りで集計します。
| var family = new []{ new { Name = "父", Age = 40, Sex = "男" }, new { Name = "母", Age = 40, Sex = "女" }, new { Name = "娘", Age = 10, Sex = "女" }, new { Name = "爺ちゃん", Age = 70, Sex = "男" }, new { Name = "曾婆ちゃん", Age = 100, Sex = "女" }, new { Name = "曾曾婆ちゃん", Age = 125, Sex = "女" } }; string startVal = string.Empty; var AggNamePerSex = from f in family group f by f.Sex into g select new { Sex = g.Key, AggName = g.Aggregate( startVal // 初期値 , (running, next) => running += next.Name + "," // 集計処理 , result => result == string.Empty ? result : result.Substring(0, result.Length -1) // 終了処理 ) }; foreach (var sexGroup in AggNamePerSex) { Console.WriteLine(sexGroup.Sex + " : " + sexGroup.AggName); } |
実行結果はこんな感じ
| 男 : 父,爺ちゃん 女 : 母,娘,曾婆ちゃん,曾曾婆ちゃん |
処理の方をよく見てみると、初期値(初期化)→集計処理→終了処理 とOracleやSQL Serverと似ていますね。パラレル実行などがないため、マージはありませんが(w
P.S. ソースを見てみると、もはやC#のソースに見えない…というか、なぜ「C」って付いているんだろうw
2008年6月30日
#
前回のOracleでユーザ定義集計関数を作成したので、今度はSQL Server 2005で作ってみた。ちなみに、わんくま内のblogを検索してみたらSQL CLRについてのエントリがあまり無い。
人気茄子…やろうと思えばDataTableでガリガリやれないこともない…
…
まあ、これからですよ!これから!ははは
気を取り直して、SQL CLRで作るユーザ定義集計関数。いってみよー
大まかな流れ
Oracleの場合と違い、SQL Serverでユーザ定義集計関数を作成する場合、アセンブリを作成する必要がのですが
- .NETでコーディングしてアセンブリ作成(署名忘れずに※1)
- 1で作成したクラスを紐付けたユーザー定義集計関数を定義
と、あまり変わらないじゃん♪ (え?アセンブリを署名するのが面倒?まあ、やらないでもいい方法があるんで♪)
ユーザー定義集計関数インターフェース
インターフェースというと語弊が若干あるのですが、要する実装する必要があるインターフェース&定義する必要のあるメソッド及びアトリビュートです。
クラスに対して必要なもの
- Microsoft.SqlServer.Server.SqlUserDefinedAggregate アトリビュート(クラス)の定義
- Microsoft.SqlServer.Server.IBinarySerialize インターフェースの継承
メンバに対して必要なもの
- public void Init()
- public void Accumulate(SqlString value)
- public void Merge(CsvConcatenation other)
- public SqlString Terminate()
- public void Read(BinaryReader r) ※IBinarySerializeの実装
- public void Write(BinaryWriter w) ※IBinarySerializeの実装
うム。上の四つはOracleと一緒だ(笑
ということで、サクサクいきましょう。
CsvConcate集計関数
こういう、関数の実装部分を定義するクラスの名前っていつも悩みますね。動詞にするかしないかってことで。今回はSQL Server 2005に登録する関数と同じ名前にしたかったので、CsvConcateにしましたが、クラス名だけならCsvConcatenationにしちゃってもいいんですよね。
とまあ、クラス名の話はさておき、文字列をCSV形式で集計してくれるユーザー定義集計関数を作りたいと思います。
まずはMicrosoft.SqlServer.Server.SqlUserDefinedAggregate アトリビュートの定義
|
[Serializable] [Microsoft.SqlServer.Server.SqlUserDefinedAggregate( Microsoft.SqlServer.Server.Format.UserDefined, //シリアライズ形式(ネイティブかユーザ定義) IsInvariantToNulls = true, // NULLに対して不変かどうか(NULLを集計しない場合はTrue) IsInvariantToDuplicates = false, // 重複値に対して不変かどうか(重複した値を集計しない場合はTrue) IsInvariantToOrder = false, // 現在は未使用(未実装) MaxByteSize = 8000)] // MAXサイズ public class CsvConcate : Microsoft.SqlServer.Server.IBinarySerialize |
定義の内容はコメントの通り。NULLや重複値については用途に合わせて使い分けて下さい。
次はInit~Treminateまでのメソッドです。
|
/// <summary> /// 中間結果を保持 /// </summary> private StringBuilder intermediateResult;
/// <summary> /// 初期化 /// </summary> public void Init() { intermediateResult = new StringBuilder(); }
/// <summary> /// 実際の集計処理 /// </summary> /// <param name="value"></param> public void Accumulate(SqlString value) {
if (value.IsNull) { intermediateResult.Append(string.Empty).Append(','); } intermediateResult.Append(value.Value).Append(',');
}
/// <summary> /// 部分計算された場合のマージ /// </summary> /// <param name="other"></param> public void Merge(CsvConcate other) { intermediateResult.Append(other.intermediateResult); }
/// <summary> /// 終了処理 /// </summary> /// <returns></returns> public SqlString Terminate() { string output = string.Empty; // 最後のカンマはおさらば if (intermediateResult != null && intermediateResult.Length > 0) output = intermediateResult.ToString(0, intermediateResult.Length - 1); return new SqlString(output); } |
そんでもってIBinarySerialize インターフェースの実装(Microsoft.SqlServer.Server.Format.Nativeの場合は必要なし?)
|
#region IBinarySerialize メンバ
void IBinarySerialize.Read(BinaryReader r) { if (r == null) throw new ArgumentNullException("r"); intermediateResult = new StringBuilder(r.ReadString()); }
void IBinarySerialize.Write(BinaryWriter w) { if (w == null) throw new ArgumentNullException("w"); w.Write(intermediateResult.ToString()); }
#endregion |
アセンブリを署名するのを忘れずに(キーペアは「sn」などで作成しましょう)※1
ユーザー定義集計関数の登録
さて、署名付きのアセンブリが作成できたのなら、あとは登録するだけです。とりあえず、やることは三つ
- アセンブリの登録
- ユーザー定義集計関数の定義(クラスとの紐付け)
登録するアセンブリの配置場所ですが、こいつは適当「UserLib」に切っておいて、そこに作成したアセンブリ「StringUtility.dll」を配置します。
| C:\Program Files\Microsoft SQL Server\90\UserLib\StringUtility.dll |
(別にSQL Serverと同じフォルダでなくても構いません。)
それと、CLR統合機能を予め有効化する必要があるので、以下のSQLを発行(参考文献:夏椰さんのを参照)
sp_configure 'clr enabled', 1 GO RECONFIGURE GO |
あとはこいつを登録してやるだけです。以下のSQLを発行
|
-- アセンブリのパス declare @asmblyPath nvarchar(1000) set @asmblyPath = 'C:\Program Files\Microsoft SQL Server\90\UserLib\StringUtility.dll'
-- アセンブリの登録 CREATE ASSEMBLY StringUtility FROM @asmblyPath WITH permission_set=Safe; GO
-- ユーザー定義集計関数の定義 CREATE AGGREGATE Concatenate(@input nvarchar(4000)) RETURNS nvarchar(4000) EXTERNAL NAME [StringUtility].[Wankuma.Ganf.SqlClr.StringUtility.CsvConcate]; GO |
これで、完成。では実際にNorthWindで使ってみましょう。(AdventureWorksでもいいですが、あれは結構件数が入っているので、バッファがすぐにあふry)
使い方
こちらも、Oracle同様、他の集計関数と同じ使い方です。
|
select country, dbo.csvconcate(employeeid) from employees group by country |
参考文献
MSDN CLR ユーザー定義集計の要件
http://technet.microsoft.com/ja-jp/library/ms161551.aspx
ユーザー定義集計関とは違いますが、数夏椰さんのとこでいくつかSQL CLRが公開されています。
夏椰の庵 - Secluded Spot of Kaya - BOX
※1 アセンブリの署名を行わなくても、アセンブリの登録は可能です。その場合は、データベースのTRUSTWORTHYをONにしましょう。
2008年6月22日
#
久しぶりにブログを書いています。暇になったわけではないのですが、モチベーションが若干上がってきたので、いい機会ってことで書いています。
んで、話題はOracleさんのユーザ定義集計関数についてです。集計関数や分析関数はOracleが用意しているものでそれなりに事足りてしまったりもするのですが、稀に使いたい場面も存在していたりします。(たまにだけどねw)
大まかな流れ
そんなこんなで稀に使いたいユーザー定義集計関数ですが、作成の大まかな流れは次みたいな感じになります。
- ユーザー定義集計関数インターフェースを実装するTypeとType Bodyを定義(オブジェクト型として定義)
- 1で作成したTypeと紐付けたFunction(集計関数)を定義
と、そんな、難しいものじゃありません。PL/SQL書けるぐらいの人ならお茶の子さいさいです。
ユーザー定義集計関数インターフェース
ユーザー定義集計関数インターフェースで実装する必要がある必須メソッドは次の四つ
- ODCIAggregateInitialize(actx IN OUT )
- ODCIAggregateIterate(self IN OUT , val )
- ODCIAggregateMerge(self IN OUT , ctx2 IN )
- ODCIAggregateTerminate(self IN , ReturnValue OUT , flags IN number)
上から順に、初期化メソッド・実際の集計処理のメソッド・マージのメソッド(パラレル処理した場合の結果のマージ)・終了処理となります。
返却値はすべてNumber型ですが、ODCIConstという定数を管理しているパッケージがありますので、利用しましょう。(SuccessとError以外は基本使いません)
agg_csv集計関数
文字列をカンマ区切りで集計する集計関数を作成します。agg_csvと命名します。C#なんかの命名に慣れていると、大文字小文字やアンスコの使い方が違うのでかなり微妙に思える方もいるかもしれませんが、我慢して下さい。
まずは、オブジェクト型の定義です。
|
-- CSV集計関数 Type定義 CREATE OR REPLACE TYPE t_agg_csv AS OBJECT ( g_string VARCHAR2(32767),
STATIC FUNCTION ODCIAggregateInitialize(actx IN OUT t_agg_csv) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_agg_csv, val IN VARCHAR2 ) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_agg_csv, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_agg_csv, ctx2 IN t_agg_csv) RETURN NUMBER ); / |
次に、オブジェクト型の実装部分の定義です。
|
-- CSV集計関数 Type Body定義 CREATE OR REPLACE TYPE BODY t_agg_csv IS STATIC FUNCTION ODCIAggregateInitialize(actx IN OUT t_agg_csv) RETURN NUMBER IS BEGIN -- 初期化 actx := t_agg_csv(NULL); RETURN ODCIConst.Success; END;
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_agg_csv, val IN VARCHAR2 ) RETURN NUMBER IS BEGIN -- カンマ区切り self.g_string := self.g_string || ',' || val; RETURN ODCIConst.Success; END;
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_agg_csv, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER IS BEGIN -- 最後のカンマはおさらば returnValue := RTRIM(LTRIM(self.g_string, ','), ','); RETURN ODCIConst.Success; END;
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_agg_csv, ctx2 IN t_agg_csv) RETURN NUMBER IS BEGIN -- パラレル実行されても、それぞれを単純に結合 self.g_string := self.g_string || ',' || ctx2.g_string; RETURN ODCIConst.Success; END; END; / |
最後に、集計関数の定義です。これを定義しないといくら上のTypeを作成してもダメです。たくみに、パラレル実行可能と定義しています。
|
-- CSV集計関数 CREATE OR REPLACE FUNCTION agg_csv(p_input VARCHAR2) RETURN VARCHAR2 PARALLEL_ENABLE AGGREGATE USING t_agg_csv; / |
NULLだった場合の判定などは全体的に外してあります。あまり余計なものを付けたくなかっただけなので、実際に使用する場合はその辺を調整して下さい。
使い方
使い方は通常の集計関数なんかと同じです。
|
-- 事業部(department)ごとにEmpIDを集計 select department_id, agg_csv(employee_id) from hr.EMPLOYEES group by department_id |
参考文献
Oracle Databaseデータ・カートリッジ開発者ガイド - 11 ユーザー定義集計関数
Oracle Databaseデータ・カートリッジ開発者ガイド - 22 ユーザー定義集計関数インタフェース
2007年7月28日
#
最近、標準文書の修正などをやっているんですが、Wordのファイルサイズが保存する度に300kBずつぐらい大きくなって困ってます。
試しに変更履歴を取らないようにしてみても同じ。本々あまり大きなサイズではなかったのですが、いつの間にやら2.0MBを超えて、困った困った。
(かなり)ぁゃιぃところとしては、テーブル内の一行を改行部分を含めて色を変えたりすると、そのスタイル全体が変更後の色に書き換わってしまったりしていたり、さらにそこからCtrl+zで書式を戻すとそのスタイルを適用されている文がコピーされたりと中々不穏な動きをしてくれます。(ちなみに、スタイルの履歴も保存しないようにしてます。)
とりあえず、一旦Word文書をXMLとして保存して閉じ、更にそのXMLから別のWord文書に戻すってことで直ったんですが、一体全体何が原因だったんでしょう…
うーん、めちゃ疑問解決(;^ω^)
2007年7月16日
#
仕事でMVCやプレゼンテーション部分のアーキパターンについての話題が挙がったので、真面目に調べてみました。ということでノート代わりにここを使用します。間違っていたら指摘して下さいね。
1. 発祥
1978年にSmalltalkを開発していたXerox社の研究所で生まれる。その後、MVCの実装を記述した論文「Applications Programming in Smalltalk-80(TM):How to use Model-View-Controller」が発表されるとその有用性から多方面へと広がる。
2. 構造
UIの構造やビジネスロジック(データ含む)などの利害関係の異なるそれぞれの要素に対し、どのようにすればそれらを奇麗に分離することができるのか?という問題に対する一つの解として登場したのがMVCです。MVCではビジネスロジックやUI、ユーザからの入力の三つ(つまり、処理/出力/入力)をそれぞれModel/View/Controllerの3つの要素に分離し、役割を設けます。
| Model |
ドメイン(ドメインレイヤーではない)についての情報や捜査を担当する要素。主にビジネスロジックを実装します。 |
| View |
ユーザへの情報の表示を担当する要素(UI)。Modelのデータを出力します。 |
| Controller |
ユーザからのアクションを受け、ModelやViewの操作を担当する要素。 |
※ 実線は直接的な関連性、点線は間接的な関連性を示す。
3. 分離と依存性
MVCの最も重要な点として、Presentation(ViewとController)とModelの分離が挙げられます。ModelをPresentationから独立させ、更にPresentationに依存させないことにより次のメリットが得られます。
- Modelにおける処理が簡素化される。
- Model単体でテストを行うことが可能である。非UI要素なので、単体テストも比較的容易に可能である。
- Presentationの修正をModelをいじらずに行うことが可能となる。
尚、Modelに関しては「Passive Model」と呼ばれるパターンと「Active Model」と呼ばれる二つのパターンが存在します。Passive ModelはModelがControllerによって排他的に使用される場合は使用することができます。例えば、Webアプリケーションなどは基本Modelのデータは顧客単位で保持している場合が多く、この場合ModelはControllerより(実質的に)排他的に利用されると考えてよい。とうぜんModelを共有する可能性が出てくる場合もあるが、楽観ロックや悲観ロック等で同時実行制御を行うことで問題を回避することができる。
一方、複数のViewからModelを参照し、そのどれかのControllerによりModelが更新され、その更新を各Viewに反映する必要がある場合Passive Modelを使用することはできません。Modelの変更をController抜きにViewへ反映する必要がある場合、「Active Model」を使用することになります。Active Modelでは、Modelの変更をViewに反映する必要があることから、Modelに依存しているViewを管理するどこかで必要があります。Model要素にView要素への直接的な依存性を持たせてしまうと、Model View Controllerと分離させた意味が無くなってしまうので、依存性を管理するコレクションを利用したり、Observerパターンを利用することによりViewとModelの直接的な依存性を回避する必要があります。
(ちなみに、この辺でよくある勘違いとして、PresentationがModelに依存しないと思ってしまう人がいます。これは大きな間違いで、PresentationとModelは分離しても、PresentationからModelへの依存性は必ず発生します。重要なのはModelからPresentationへの依存性を無くすことです。というか、依存性無しじゃプログラム作れないよっ)
もう一つViewとControllerの分離もありますが、こちらはPresentationとModelの分離ほど重要視されていません。これはViewとControllerを明確に分離すること自体難しい場合が多いからです。(ただWebアプリケーションなどはそうも言ってられないみたいですが…)
4. MVCの実装と派生パターン
MVCの実装方法としてはPage ControllerやFront Controllerパターン、MVCからの派生パターンとしてMVP(Model View Presenter )があります。が、まだしっかりと調べきっていないので、また次の機会に説明します(;´Д`)
参考文献
[1] Model-view-controller wiki
[2] MVC - XEROX PARC 1978-79
[3] Applications Programming in Smalltalk-80(TM) : How to use Model-View-Controller
[4] モデルビューコントローラ MSDN
[5] Martin Fowler, エンタープライズアーキテクチャパターン, ISBN4-7981-0553-8
[6] GoF, デザインパターン, ISBN4-7973-1112-6
# 書き始めたころに大きな地震がありました。またもや新潟らしいです。北陸地方の人大丈夫ですかね…
2007年7月8日
#
かなり久しぶりのブログですが、助手こと狆(ちん)のなうらが1歳になりました!うちに来たときは1.5kgぐらいしかなくて小さかったけど、今や3.8kgと当時の2.5倍に。
記念にちょっと回想してみました。長くなるかもしれませんが、勘弁してくだせえw
2006年11月
うちに来たばかりのときです。小さいときはどんなものであっても可愛いねw一番左の画像で噛んでいるのは私の足。といっても歯がほとんど生えていなかったので痛くありません。そーいえばご飯もドライフードをお湯でふやかしてあげてたっけ…ふやかし足りないとゲリピーに(;´Д`)
2006年12月
12月。左の画像はかなりお気に入り。ボールを与えたら威嚇していたので思わず写真を撮ってしまいましたw他の画像は全て眠っている姿なんですが、一番右は・・・たまに酔っ払いオヤヂの様な姿で寝ます(;´Д`) ちなみに、この頃から五種混合ワクチンの接種も完了して散歩を開始してました。数百メートル散歩すると動かなくなって、毎回抱えて帰ってましたw
2007年1月
体重も2kgを超え、来た頃に比べれば幾分成犬に近くなってきました。散歩もこなれてきたのか、色んなところに顔を突っ込んでは結膜炎になってましたw 眼の下とかが腫れて痛々しいんですよね~…二日もせず治るけど。
2007年2月
「なうらはソファー占拠のスキルを覚えた!」
はた迷惑なスキルを覚えたもんです…ベロがちょろっと出てるのはデフォルト設定です。既定値。
2007年3月
春眠暁を覚えず(朝写真を撮ったわけじゃないです)。結構立派になったんだけど、尻尾の毛がまだ子犬だと物語ってますね。散歩のときにおばちゃん達からいつも「かわいいね~」とか「まだ小さいんですか~?」とか言われます。色々と声をかけられるのですが、狆だと気づく人はほとんどいない・・・シーズーじゃありませんから!
2007年4月
毛もかなりもっさりしてきました。もっさりしてきたせいか、気温が暖かくなってきたせいか、よく口をあけます。ブサカワイイよね?犬飼ってる人は分るよね?ねっ!?
2007年5月
写真が全て携帯に…取り出すのが面倒なので後で付け加えておきます…orz
2007年6月
気温が高く湿気が多いのとおやつでアレルギー反応を起こしました。蕁麻疹っぽいのを自分で噛んで皮膚がただれてしまったので病院へ。抗生物質をもらって(体重が軽いので1日2回、各1/3粒)無事解消。写真はソファーの上で好き勝手している写真ばかり…すぐに乗っかるんですよ(ノД`)
2007年7月
そして最近のなうら。この前ペットのコジマで買ったデンタルケア骨が気に入ってるみたいです。ちなみに一番右の写真、換毛期が過ぎかなり毛が減っているのが分かります。立った写真が無いのですが、腕の飾り毛なんかもかなり貧相なことになってたりしますw
最後になうら助手の体重の遷移をアップして終わらせようと思います。ひそかにExcelで管理していたので、ポチっとな
| 日付 | 12/1 | 12/11 | 12/15 | 12/27 | 1/10 | 2/10 | 3/6 | 3/20 | 4/20 | 5/22 | 6/2 | 7/8 |
| 体重(kg) | 1.55 | 1.8 | 1.92 | 2.06 | 2.3 | 2.8 | 3.08 | 3.25 | 3.44 | 3.7 | 3.65 | 3.8 |

見事に収束。バグ 曲線もこれぐらいを目指さねばっ(7ヶ月は長すぎるけどねw)。
2007年5月24日
#
前にりょーいちさんの記事(COMの学習)で「Inside COMやEssential COMが手に入らない」なんてのがありましたが、実は私も同じ状態が続いています。
前に紀伊国屋のWebサイトにEssential COMがあったので速効で頼んでみたところ、数日後に品切れ&ご免なさいメールが飛んできてがっかりしたものです。
しかし!諦めることなかれ!!世の中には絶版したような本でも復刊させちゃおうってサイトがちゃんとあります!その名も
復刊ドットコム
リクエスト投票によって本を復刊・復刻させるサービスなんです。
もうね、速効で投票。
ユーザ登録して、「Inside」って検索かけて投票ボタンをぽちっと。これで完了。
投票数から見て先はまだまだ長いかもしれませんが、やっぱ昔の技術も知っておきたい!Inside COMが欲しい!って方は是非是非投票して一緒にゲットしましょう!!
2007年5月22日
#
日曜辺りから熱(一時39度あった!)と胃腸炎(これまたすこぶる痛い。激痛)に悩まされて会社も傷病休暇を取っていたのですが、
今日ふと気がついたら顔面の筋肉が痛い。特に頬の上辺りの筋肉が痛い。
腹痛に耐えているとき、歯をくいしばってしかめっ面になっていたのが原因っぽい…
顔面筋肉痛なんて初めてだったからブログに書いてみましたw(最近書いてなかったし)
# ちなみに、体重は三日で1.5kg減りました。ダ、ダイエット成功?(滝汗
2007年5月12日
#
米MS、HTML構造やレイアウトを検証できるWeb制作者向けIEプラグインを正式公開 :Impress Watch
MSが何か出しましたね。FireFoxのDOM Inspectorとほぼ同じような機能を持ったIEアドオンのみたいです。
概要としては
- WebページのDOMを表示&修正
- 特定の要素を検索/選択可
- IEのセッティングをオフにしたりできる
- HTMLオブジェクトのいろいろな情報を閲覧可
- 選択したテーブルやセル、イメージのアウトラインを表示
- HTMLやCSS、WAI、RSSフィードをチェック(validate)できる(Validateしてくれるページに飛ばされる)
- イメージの情報を表示
- ブラウザを簡単にリサイズ
- ルーラーあります
- 要素のスタイルの値からそのスタイルを定義している場所を逆引きできます
- 要素の背景などで使用されている色を抽出できます
だそうです。この他、Cookieの内容を確認したり削除できます。DOMを表示できるデバッガとしては、前に紹介した Web Development Helper というのがありますが、画面の内容を修正するということにおいてはIE Developer Toolbar の方が良いみたいです。特に要素を検索するときに画面上の要素を直接選択することができるので楽そうです。例えば、ブログのCSSを自分用にちょっと変更する場合なんかはIE Developer Toolbar を使えば楽にできちゃいそうです。
動作も重くないのでどうっすか?
2007年5月7日
#
Javascript Intellisense in Visual Studio "Orcas" : ScottGu's Blog
買ったばかりのPCにOrcasを入れる勇気が無く、まだダウンロードしていないのですが、上記のブログによるとOrcasではJavascriptにもインテリセンスが効くんですね。前々から欲しかった機能だったのですが、Orcasで使えるように。これでスペルミスに悩まされずに済みます!ぐっじょぶ。
# そういえばわんくまの懇親会で誰かが話していたような話していなかったような。
# お酒はほとんど飲んでないのに覚えてないや(滝汗