徒然技術日記

Object.prototype.__noSuchMethod__

サイバーエージェントにインターンに行ってきた話

f:id:Nodaguti:20151016003335j:plain

インターンが終わってからだいぶ間が空いてしまいましたが,

nodaguti.hatenablog.com

で書いたとおり9月いっぱいサイバーエージェントインターンに行ってきました.

ちなみにハッカソン(TECH CAMP)ではなく, 就業型インターン(弟子入り) の方です.

業務内容

www.amebaownd.com

アメブロと比べて残念ながら知名度が低めなサービス(自分もインターンに応募するまで知らなかった) Ameba Ownd のチームにフロントエンドエンジニアとしてジョインしました. フロントエンドだけで自分以外に7人もいるチームでした.全体では30人くらいだったと思います.

中身は CoffeeScript + Angular.js + Webpack + Jade + Stylus という構成で, 規模としては gulp build でフルビルドすると2-3分かかるくらいでした. というわけで,コーヒーコーヒーした1ヶ月間でした.

一方自分のスキルセットは

  • JavaScript は書ける.
  • CoffeeScript は食わず嫌いしてた.
  • Angular.js, Webpack, Jade, Stylus, Gulp, etc.: 名前は知っているけれど...
  • git: pull req したことない.

という惨状でした.

言ってみれば自分のスキルは10年くらい前のフロントエンジニアみたいな感じであり,最初のうちは割ときつかったです.

しかし,その分非常に勉強になったと感じています. はてブに流れてくるものを読むだけでなく,とりあえず手を動かしてフレームワークに触れてみることの重要性を実感しました.

より具体的に

環境構築が終わった段階で,まずはコードリーディングとウォーミングアップを兼ねた簡単めなタスクということで, ヘッダー部分のナビゲーションをウィンドウの幅にあわせて "More" に収納する部分の修正を割り振っていただきました.

しかしながら,その場の全員(自分含む)が軽いタスクだと見積もっていたこれが実は罠案件で, 最終的には該当部分の Controller を一からリライトし, かつ各テーマの DOM 構造および CSS を変更しなければならないという割と大変なタスクでした... 結局リリースできたのはインターン最終日あたりだったと思います.

他には,何件かのバグ修正と,詳しくは書けないですが新規ページの実装を行いました.

1ヶ月は長いかと思っていたのですが,他のバイトとの兼ね合いから週3での出勤だったこと, シルバーウィークがあったことなどから,実質的な出社日数は10日あまりでした. 期間が短かったことと,予想以上に1stタスクが伸びてしまった影響で新機能のリリースまでいけなかったのが残念です. (未完成状態で他のメンバに引き継ぐ形になりました)

また,自分がいた時期は,万行単位の機能が1週間に最低1つは投入されるような状況で, まわりが圧倒的スピードで開発しているのに気押されていたというのもあります. 逆に言うとよく自分なんかを受け入れてくれたなーという感じで, 忙しい合間をぬっていろいろアドバイスをくださったメンバの方々には感謝してもしきれないです.

インターンシップの環境について

MBP (機種がちょっと古めだったのと,キー配列がJIS配列だったのがちょっと残念だった) と Thunderbolt Display を貸与されました. 自宅のEIZO 24inchディスプレイ よりも遥かに快適だったので,やはりディスプレイは大きければ大きいほどよいという印象です.

無料のウォーターサーバーとドリンクサーバー(紙コップに飲み物が注がれるやつ)があり, 無限コーヒーと無限紅茶花伝で飲み物には困りませんでした. また,社内販売のお弁当があり,400円程度でおいしい弁当を食べられました. 1つ上の階にあった全品50円のアイス自販機でアイスを買いそびれたのが唯一心残りな点です :)

また,よく「サイバーの社員はリア充」と言われますが, 机にフィギュアが置いてあったり,Macに美少女キャラのステッカーが貼ってあったりという事象は 確かに観測できなかったので,ある意味エンジニアの方に対しても当てはまるのかもしれません.

人事の強力なバックアップ体制

インターンに関して,人事の方が強力にバックアップしてくださったのが特徴的でした.例えば:

  • 週1の面談

    人事の担当の方と毎週面談があり,目標,現状の課題,悩みなどを共有しました.

    こう聞くと面倒臭く感じるかもしれませんが,むしろ漫然と目の前のタスクをこなすのではなく, 現状の整理をこまめに行うことができ,明確な目的意識を持ってインターンに取り組めるという点で有意義でした.

  • インターン生交流ランチ・飲み会

    人事の方が他のインターン生や社員の方との飲み会やランチをセッティングしてくださり, 積極的に交流の機会を持つことができました.タダ飯最高!

最後に

最終日に Ownd チームの方全員から無事に修了したことをお祝いしていただきました. 賞状,フロントチームからの寄せ書き,高級そうなボールペンをいただきました.

f:id:Nodaguti:20151016003303j:plain

写真には写っていませんが賞状の裏にはメンターと人事の方からメッセージがびっしり書かれています. 短い間しかいなかったにも関わらずいろいろ用意してくださり,本当にありがとうございました!(ボールペンは早速愛用しています)

サイバーエージェントインターンは,cutting-edge な技術を用いたスピード感のある開発を経験できるのみならず, 他のインターン生や社員の方との人脈を広げることのできる貴重な機会だと思います.

来年インターンを考えている方は,ぜひサイバーエージェントにもエントリーしてみることをおすすめします!

chaikaの開発を無期限停止します

github.com

chaika は,近くリリースする 1.8.0 をもって開発を無期限停止とします. より正確には,nodaguti は chaika の開発から手を引きます.

2013年からの短い期間でしたが,利用してくださった皆様,開発上のサポートしてくださった方々など, 多くの方に支えられて開発を継続することが出来ました. 本当にありがとうございました.

振り返ってみると,モチベーションの高い時と低い時の差が激しく, 頻繁にリリースしたかと思えば1年以上更新しない時期が続いたりする不安定な開発スタイルでした. また,テストを適当に済ませてしまうひどい癖のために,バグが混入することもしばしばでした.

ご迷惑をお掛けし申し訳ありませんでした.

理由

直接的かつ最大の理由は「XUL/XPCOMを廃止し,WebExtensions API へ移行することが発表されたこと」(下記記事参照)です.

rockridge.hatenablog.com

chaika はここのところ,掲示板への対応(dat取得処理,datパース処理など)をプラグイン化するシステムを開発中でした. これは,2ch.net/bbspink.com からの締め出しを食らったことを受けて, あらゆる掲示板に対し,ユーザーがプラグインを追加するだけで対応できるようにするものです.

それまでは,コード中に 2ch.net/bbspink.com/2ch互換掲示板, したらば,まちBBS という 3種類の掲示板に向けた記述が直接記述(ハードコーディング)されており,難解なコードとなっていました.

これを一からリライトし,ついでに File IO を非同期に変えることで高速化も狙うというかなり大規模な開発を進めていたところでした. この大規模リファクタリングを実現するためには,約3万行ある chaika のコードをほとんどすべて書き換える必要があると見積もっていました.

しかし,最近 XUL/XPCOM が廃止されるというニュースが流れました. chaika は「旧来型」のアドオンであり,XUL/XPCOM によって作られています(Add-on SDK も使用していません).

WebExtensions API だけで chaika の機能が全て実現できるかどうかは,仕様が固まっていないためなんとも言えませんが, この「仕様変更」に対応するためには chaika のコードを全て書き直す必要があるということは確実です.

chaika は機能が多く,各機能や設定が複雑に絡み合っている上,歴史的な経緯による仕様も存在します. そのようなアドオンを,一からコードを書きなおして忠実に再現することは,私個人の手では極めて困難であろうとの結論に達しました. 技術力不足であるとの謗りは甘んじて受ける所存ですが,何卒ご了承ください.

今年2月に bbs2chreader/chaika Part45 にて

私としては flyson さんが 2004 年に開発を開始した時から 10 年以上も続いている歴史に終止符を打つことは現時点では考えておりません。

と発言してから1年もしないうちにこのような決定をしなければならないのは大変残念ですが, どうか事情をご理解いただければ幸いです.

chaika 1.8.0

現在の開発版に対し,e10s に対応するための最低限の変更を加えたものを 1.8.0 としてリリースする予定です.

元々は上でも書いたように大規模なリファクタリングを行っているところであったため, 新旧のコードが入り混じった非常に汚い状態でリリースしなければならないのがちょっとアレですが, リファクタリングを続ける気力がもうないので... (リファクタリングしても1年くらいで動かないコードになるため)

今後に向けて

今回のことは,chaika の開発引き継ぎや,コードの再利用などを禁止するものではありません. ライセンス(MPL 1.1/GPL 2.0/LGPL 2.1)に沿った利用であれば,なんら問題なく使用可能です.

私自身としては,bbs2chreader と chaika をあわせて8年ほど使っており, ブラウザと一体型の専用ブラウザの快適さからは抜け出せそうもありません. WebExtensions API の仕様が固まり,専用ブラウザが作れそうであるという判断に達すれば, なんらかのアドオンを作成したいと考えています.

サイバーエージェントとドワンゴのインターンシップに参加します

これは以下の記事の派生記事です.

nodaguti.hatenablog.com

運良くサイバーエージェントドワンゴインターンに参加させていただけることになったので,面接の体験談などを書きたいと思います.

サイバーエージェント

書類審査→1次面接→2次面接でした.9月いっぱいお世話になる予定です.

志望動機

申し込んだのは「弟子入り (テクノロジーコース)」です.インターンのサイトに「インフラコース」があったので,Yahoo! と同じ理由でインフラコースに参加する目的で応募しました.

1次面接

1次面接は人事の方が面接官でした.この時点で Microsoft, はてな, Yahoo! Japanに落ちたことが判明しており,選考に通ったものがなかったため,かなり落ち込んだ状態で面接に行ったのを覚えています.

事前の提出書類ではどのコースを選択するのか?というのは書かないのですが,自分の場合自己アピールにポートフォリオGithub のアカウントを書いたことで,完全にフロントエンドに応募する人だと思われたらしく,インフラ系のことがやりたいみたいな話をしたらかなり驚かれました.

結局,実務に関わる以上,インフラ素人を現場に放り込むわけにもいかないので,フロントエンドのサービス開発をしつつ,ミドルウェアのチューニングもちょこちょこ勉強してみる?みたいな話の流れになりました.フロントエンドで大規模開発もやってみたいし,インフラにも未経験だけど関わってみたい,みたいなめちゃくちゃなことを言っていたのをうまく誘導して話をまとめてくださり,面接官の方には非常に感謝しています.

その場で1次面接通過となり,2次面接の日程を聞かれました.

2次面接

2次面接はエンジニアの方2人との面接でした.どのようなことをやりたいのか?について技術的にさらに突っ込んだ話を訊かれました/しました.

どちらかというと選考というよりは,インターン生の学びたいことと,企業側が提供できる業務内容との確認・すり合わせ的な意味合いが強いように感じました.

Firefox のアドオン開発していて,JavaScript が好き,Twitter で情報収集しています,と話しただけで,じゃああの人とかこの人とかフォローしている感じでしょ?と一発で当てられてしまったのが印象に残っています.

備考

サイバーエージェントインターン面接については様々な情報が流れており,「面接官のリア充オーラがすさまじかった.技術的なことは聞かれなかった」「面接官からの質問はほとんどなく、「時間を与えるから自分をプレゼンして」って感じ」などがありますが,自分の場合は:

  • 面接官は普通の人だった.
  • なぜこのインターンに参加しようと思ったのか,どんなことがやりたいのかについて特に重視している感じだった.
  • ポートフォリオを事前に提出したのも影響しているのか,その内容をもとに技術的な詳細を聞かれた.

という感じで,参加するコースや面接官によってだいぶ面接内容が異なるようです.

ドワンゴ

書類審査→面接でした.10-12月でお世話になる予定です.

面接

実は,募集ページに「社内にて選考」とあったので面接があると思っておらず,面接を実施するとのメールが来た時は驚きました.日程連絡の電話でしどろもどろになってしまい,申し訳なかったです.

面接では,サイバーエージェントと同じく何をしたいか,どういうサービスに関わりたいか,およびポートフォリオの内容を踏まえて技術的なことについて聞かれる,という感じでした.

ニコニコ動画に関わりたい」と話したところ,「じゃあどういうふうに改善したらいいと思う?」と訊かれ,ありきたりなことしか返せず,「それすでに検討したことある」と言われてしまったのが残念でした.「これからは新しいサービスを考案できるエンジニアがもっと必要になる」と話されていたのが印象的でした.

また,面接官の方に chaika のユーザーの方がいらっしゃったのでテンションが上がり,2chAPI が導入されたけど今後どうするつもりなの?みたいな話で盛り上がりました.実は chaika を実際に使ってくださっている方に直接お会いしたのは初めてのことで,本当に嬉しかったです.

まとめ

  • 面接では緊張で論理が破綻していたり内容がまとまっていなかったりとだいぶアレな感じだったが,なんとか通った.
  • やはり自分の得意分野で直球勝負することが大事かも.
  • インターンが終わる頃にまた様子について書きたいと思います.

インターンシップの応募にお祈りされた原因を分析した (Microsoft, はてな, Yahoo! Japan)

これは以下の記事の派生記事です.

nodaguti.hatenablog.com

選考に落ちた企業について,その原因を探ってみたいと思います.今後応募される方の参考になれば.

Microsoft

MSR (Microsoft Research) ではなく MSD (Microsoft Development) の方です.書類選考で落とされました.

提出物

  • 履歴書 (日本語): A4 1枚
  • 履歴書 (英語): A4 1枚
  • プログラミング経験とプロジェクト内容をまとめたドキュメント: A4 3枚以内

所感

マイクロソフト、アビームのインターン選考。ES通過!(マイクロソフトはテクニカルスクリーニングで落選) : 就活奮闘記

には,

学歴フィルターかと思ったが、同じ大学の同期で落とされた人もいたので、ある程度大きなプロジェクトを作っていれば通過したのではないか、という結論。

と書かれていたので,chaika の開発もしているし書類選考は通るだろうと高をくくっていました.

しかしながら書類審査で見事に落選.原因として考えられるのは,

  • 英語の履歴書が適当すぎた.
    • プロジェクトについてのアピールは専用のドキュメントがあるし書かなくていいかなーと思って省いた結果,スッカスカの履歴書になってしまった.
  • プロジェクトの中から1つ選んで詳しく説明する必要があるのだが,そこで ESChat を選んでしまった.
    • 「プロジェクトの目的」「工夫した部分」などが chaika だと書きにくいと感じたからだが,結果的にあまり大規模なプログラムでないものを選択してしまった.

あたりかなと考えています.

はてな

はてなは書類選考のみで合否が決まります.東京在住の自分にとっては,京都観光もできるし,はてなは界隈では有名ということもあってかなり志望度は高かったものの,残念ながら落選.

通知メールには「最終選考まで残った」旨が書かれていましたが,

という見方も当たらずとも遠からずな気がします.

提出物

Google のフォームを使った応募画面でした.

これまでの制作物や研究内容などをまとめたポートフォリオのほか,「言語経験」「担当したいサービス」などを記入する小設問があったように記憶しています.

所感

これは純粋に「宿泊費を負担してまで東京からわざわざ呼び寄せてもらえるだけの技術力がなかった」という一点に尽きるかなと思います.

過去のインターン生の Github とかを見てみても,とても敵わないなという方が多いですし,仮に同程度の技術力の人がいて,一方が京都住まいでもう一人が東京だったとしたら,京都の人を選ぶでしょう.特に関西圏でない学生は,京都に住んでいる学生に比べてかなり選考通過のハードルが上がるのではないでしょうか?

はてなの場合は,毎年インターン生に課している事前課題を Github で公開している(2015年度事前課題, 2014年度事前課題) ので,インターン生でなくても腕試し的に解くことができるようになっています.また,事前課題を解くにあたっては上記リポジトリを fork して解答をアップロードするようになっているので,参加者の Github アカウントも探ることができます.このあたりから,はてなインターンに要求される技術力を推察することができるかもしれません.

Yahoo! Japan

フロントエンドばかりではつまらないかなと思い,最近インフラ周り(特にインフラを仮想化するあたり)が盛り上がってきているように感じていたので,そういう方面のインターンに参加してみるのもよい経験になるのではという考えから,あえて「クラウドインフラストラクチャコース」に応募しました.

結果としては,書類選考通過→面接落ち でした.

提出物

  • 書類選考
    • 学業で力を入れたこと,または研究内容 (500字)
    • 一番自信のあるプログラムについて (300字)
    • (論文の発表経験がある場合) 論文の概要について (300字)
  • 面接
    • 履歴書
    • (要求はされていないが) ポートフォリオを印刷したものを持って行きました.

所感

面接は終始なごやかな感じでした.しかし,あとでサイバーエージェントの面接を受けた時に気付かされたのですが,Webサービスをサーバー側含めて運用したことのない人間がインフラコースに応募するのは無謀だったようです.

手取り足取り教えてもらおう,という意識ではなく,期間前後を含めて集中的に学びたい!という姿勢でいたつもりだったのですが,やはり未経験ということは大きかったです.面接でも JavaScript でこういうもの作りました! という話がメインになってしまったため,おそらく面接官の内心としては「なんでこいつこのコースに応募してきたんだろう?」という感じだったことでしょう.結果的に甘い気持ちでいた私の落ち度と言えます.

ただ,ポートフォリオを持参したことはかなり好印象だったように思います.

http://www.alperithm.jp/?p=256www.alperithm.jp

の記事でもオススメされている通り,面接時の話の種にもなるので,かなり有効だと思います.

まとめ

  • もっと技術力を高めよう.
  • 「興味がある」だけでは選考に通らない.実績が伴っている分野のインターンに参加しよう.

P.S.

グーグル、アップル、マイクロソフトに就職する方法

グーグル、アップル、マイクロソフトに就職する方法

夏のインターン選考結果および傾向と対策をまとめてみた

今年の夏はインターンの夏にしよう.と思いたち,Web系企業をターゲットにインターンへ応募したので,結果などをまとめてみたいと思います.

応募した企業

辞退した/お祈りされた企業

参加する企業

共通の対策

インターン申し込みにあたって,行ったこと.

Github を充実させる

いままでの成果をアピールするために,大学の講義で作ったものや,chaika のアップローダにアップロードしただけのアドオンなど,まだ公開していなかった制作物を全て Github にアップロードしました.

また,それぞれに詳細な README をつけ,どのようなプロダクトなのかを明記するようにしました.事前に Github のアカウントを見ていただけた企業では,「READMEが詳しい」というのが好印象だったようなので,単に公開するだけでなく,簡単にでも README を記載しておくのは重要だと感じました.

ポートフォリオの作成

もともとは はてな のエントリー要件としてポートフォリオを作るという項目があったのがきっかけですが,いままで制作したものを時系列に並べたページを作成し,応募フォームに URL を書き込んだり,面接時に印刷して持っていったりしました.

  • 口頭でいろいろ紹介するよりも端的に,かつ分かりやすく示せる.
  • 文書ならば,事前に内容をじっくり推敲できる.
  • 面接時に話の種になる.

など多くのメリットがあるため,仮に求められていなくても作成しておくことをお勧めします.

内容としては,公開できない部分もあるのでスクリーンショットになりますが,大体以下のような感じのもので,プロダクト名,関連する画像,概要,工夫した点,公開場所,ダウンロード数などをまとめています.

f:id:Nodaguti:20150808111810p:plain

集合知の検索

とりあえず「企業名 インターン」などでググると情報が出てくるので,参考にしました.

詳細

以下の2ページに,個々の企業ごとに詳細をまとめています.

nodaguti.hatenablog.com

nodaguti.hatenablog.com

最後に

身の程知らずにも Amazon の Wish List を作成してみましたのでご参考まで.

この夏は充実した夏休みになりそうです!
サイバーエージェント様とドワンゴ様,どうぞよろしくお願いいたします.

クリエイティブ業界を目指す人のための ポートフォリオ見本帳

クリエイティブ業界を目指す人のための ポートフォリオ見本帳

ポートフォリオをつくろう!―新しい自己PRのための「編集デザイン」

ポートフォリオをつくろう!―新しい自己PRのための「編集デザイン」

プログラムからFirefoxのScratchpadでファイルを開き、適切にシンタックスハイライトをするには

Firefox のアドオンにおいて、AtomSublime Text のように plain text な設定ファイルをメニューから開けるようにするにはどのような方法が考えられるでしょうか。

nsIFile#launch

XPCOM を使って任意のファイルを開くためにまず思いつくのは、nsIFile#launch を使う方法です。

developer.mozilla.org

しかし、これは(おそらく)OS に処理を丸投げしているだけなため、状況や環境によっては問題が生じます。例えば、JSONXML を開きたい場合、それらがテキストエディタに関連付けられていない環境では、ウェブブラウザで開かれてしまったり、最悪該当アプリケーションがないというエラーが出てしまったりします。

nsIFile#reveal

同じく nsIFile から、reveal メソッドを使うという方法も考えられます。これは、ファイルに対して用いるとそのファイルを内包しているフォルダを開くという動作になります(Mac における Reveal in Finder のような機能)。

launch を使うよりはまだマシですが、結局 JSONXML の取り扱いに関する知識をユーザーに求めるという点においてあまりよい方法とは言えないでしょう。

nsIProcess

nsIProcess を利用して、エディタを指定したうえでファイルを開くという方法もあります。

developer.mozilla.org

この方法では、Mac/Windows/Linuxでデフォルトのエディタを変えなければならず、設定が複雑になるという欠点があります。

しかし、設定画面を作ることでユーザーが使い慣れたエディタを指定できるようにするなどの機能を提供できるという利点もあるため、ファイルをエディタで開くという動作が多くあるようなアドオンでは検討に値するかもしれません。

Scratchpad

Firefox には Scratchpad という CodeMirror ベースのエディタが内蔵されています。

developer.mozilla.org

しかしながら、開発者がどのように Scratchpad を使ったらよいかについての解説は MDN に書かれているものの、プログラムからどのように操作できるのかという点についてはドキュメントが全く存在しません。せっかく内蔵しているのにもったいない…

というわけで、本体のコードを読み解くことで判明した利用方法は以下の通りです。

let fileToOpen = ...; // nsIFile
let { ScratchpadManager } = Cu.import('resource:///modules/devtools/scratchpad-manager.jsm', {});
let win = ScratchpadManager.openScratchpad();

win.addEventListener('load', () => {
    win.Scratchpad.addObserver({
        onReady: () => {
            win.Scratchpad.removeObserver(this);
            win.Scratchpad.importFromFile(fileToOpen, false, () => {
                win.Scratchpad.editor.setMode({ name: 'xml' });
            });
        }
    });
});

まず、resource:///modules/devtools/scratchpad-manager.jsm にて定義されている ScratchpadManager を読み込みます。

そして、openScratchpad メソッドにより Scratchpad を開きます。このメソッドaState という Optional な引数をとり、初期化時のパラメータを渡すことができるようです。おそらく、Firefox の起動時に前回 Scratchpad で開いていたファイルを復元するために使われているのだと思われます。しかし、ファイル名、ファイルの内容(テキスト)、実行コンテキスト(Content or Browser)を渡せるのみであり、今回の用途には適しませんでした。

ウィンドウの読み込みを待った後は、エディタの初期化を待つ必要があります。これには Scratchpad.addObserver を用います。初期化が完了すると onReady が呼ばれます。

最後に、ファイルを読み込むためには Scratchpad.importFromFile(aFile, aSilent, aCallback) を用います。aFile は読み込むファイルを、aSilent は読み込み失敗時にエラーを表示するかどうかを、aCallback は読み込みが完了した時に呼ばれるコールバックを指定します。

JavaScript を読み込む分には aCallback を無指定にして読みこめば完了ですが、(Scratchpad は JavaScript 専用エディタのようにできているにも関わらず)他のタイプのファイルを読み込むことも可能であり、その場合はシンタックスハイライトを適切に設定しなくてはいけません。具体的には上の win.Scratchpad.editor.setMode({ name: 'xml' }); の部分がそれです。

エディタの設定は Scratchpad.editor(実体は devtools/sourceeditor/editor.js)からいろいろできるっぽく(あまり調べていない)、いじってみるとなにかおもしろいことができそうな雰囲気がします。ちなみに、editor.js には xml というモードは定義されていませんが、指定してみたら動作しました :)

まとめ

  • テキストファイルを開くなら nsIProcess か Scratchpad
  • Scratchpad を外部からいろいろやるとおもしろそう

Components.utils.import でグローバル汚染を引き起こさずにインポートする方法

Firefox 本体ではおそらくだいぶ前から使われているだろうから今更感あるし、2015年にもなって Mozilla-specific な JavaScript の記事に需要があるのかはわからないけれど、先ほどとあるコードモジュールを読んでいて知見を得たので共有します。

Components.utils.import は第2引数に何も指定しない場合、コードが書かれているスコープではなく、グローバルスコープに指定したモジュールを展開します。そのため、せっかく以下のように Module Pattern を使って書いていたとしても、グローバル汚染が引き起こされます。

(function(global){
    "use strict";

    Components.utils.import("resource://my-module/Hoge.jsm");
    // do something
})((this || 0).self || global);

Hoge === undefined; // -> false

しかしながら、第2引数に名前空間を指定して、モジュールに対しては常にその名前空間を介してアクセスするというのもコードが無駄に冗長になり、つらみが高まります。

let Modules = {};
Components.utils.import("resource://my-module/Hoge.jsm", Modules);
    
Modules.Hoge.foo();
if(Modules.Hoge.bar()){
    // do something
}

そこで有効なのが、Components.utils.import がモジュールのグローバルオブジェクトを返すということを利用し、空のオブジェクトをスコープとして渡した上で、返り値をローカル変数で受ける方法です。Object destructuring を用いることでかなり簡潔に書くことができます。

let { Hoge } = Components.utils.import("resource://my-module/Hoge.jsm", {});

返り値の利用は非推奨(use of the return value is discouraged)と MDN に書かれているのが若干気になるところですが、Firefox 本体にも多く使われているテクニックなので恐らく大丈夫でしょう。

(追記 2015/5/16 18:00) id:Syoichi さまのご指摘に基づき、Object destructuring と Shorthand Properties を誤解していたことが判明したため、上記最後の部分を修正。元文章は以下の通り。

let { Hoge: Hoge } = Components.utils.import("resource://my-module/Hoge.jsm", {});

返り値の利用は非推奨(use of the return value is discouraged)と MDN に書かれているのが若干気になるところですが、Firefox 本体にも多く使われているテクニックなので恐らく大丈夫でしょう。

さらに、Firefox 33 以降であれば Shorthand Properties が使えるので、上記はより簡潔に

let { Hoge } = Components.utils.import("resource://my-module/Hoge.jsm", {});

と書くことができます。