ホーム ブログ ページ 49

第1回 PureMVC入門

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめまして、su10です。Flex向けのフレームワークであるPureMVCについて学んだことを自分なりにまとめて解説していきたいと思います。(2012/5/25更新)

 PureMVCあるある

「うちはPureMVC使ってるから勉強しといてね」

「わかりました」

 数時間後…

「(ネット上にわかりやすい説明ない…「Cairngorm」って何だよ…帰りたいよ…)」

こんなことってよくありますよね。自分の場合は「とりあえずコード読んだらわかるだろう」と思ったらhandleNotificationが一体何なのかわからず、目から汗をかきそうになりました。

 PureMVCの基本

まずはPureMVCとは何か?最初に書きましたが、PureMVCはFlex向けのフレームワークです。Flex向けといってもJavaやC#向けもあるらしいので、これを機会に理解しておけば夢が広がります。そもそも「フレームワークってなに?」という人は「フレームワーク プリン」でググってもらうとして、まずは基礎となるMVCという概念の解説です。

Model、View、Controller

MVCはModel、View、Controllerの頭文字を取ったものです。プログラムの機能をこの3つに分けて書くことでコードがわかりやすくなります。MVCの考え方自体はRailsにもありますね。PureMVCでもこの考え方に基づき、コードを書いていくことになります。それぞれの機能は以下のようになっています。

  • ・Model … サーバとのやり取り、データの管理、ビジネスロジック
  • ・View  … ユーザに見える部分の処理
  • ・Controller … ユーザの入力などに応じてModelの機能を呼び出す

「ビジネスロジック」という単語がわかりにくいですが、要するに「ユーザに見える部分の処理とデータやデータベースの処理の間にある処理」のことです。流れとしては次のようになります。

  1. ユーザが入力を行う(View層が処理)
  2. 入力に応じてModel層の機能呼び出し(Controller層が処理)
  3. データの更新などを行う(Model層が処理)
  4. データを取得して見た目に反映する(View層が処理)

コアアクターとFacade(ファサード)

先ほど「○○層」と表現しましたが、実はPureMVCではクラスとしてModelクラス、Viewクラス、Controllerクラスが用意されていて、これら3つをまとめてコアアクターと呼びます。これらのクラスに先述のような機能をそれぞれ分けて実装していくと考えてください(実際には少し違いますが)。

また、Facadeというクラスが用意されていて、Facadeを通じてコアアクターとやりとりができます。もう少し具体的にいうと、Facadeクラスのインスタンス(もっと正確に言うとFacadeクラスを継承したサブクラスのインスタンス)経由でコアアクターの機能を利用することができます。つまり、実際にはコアアクターの3つのクラスをインスタンス化したり直接どうこうする必要はなく、コアアクターは互いを知らなくても良いのです。コアアクターに直接仕事を頼むのではなく、Facadeを通じて仕事をお願いするのです。こうすることでそれぞれのクラスの結合が疎になり、保守性が高まっています。大事なので何度も書きますが、

コアアクターはFacadeを通じてお互いの機能を利用できるので、お互いについて知っている必要はない

です。

いろいろ書いてきましたが、ここで重大発表です。実はコアアクターは先ほどMVCで述べたような仕事はしていません!(\な、なんだってェー!!/)

実際にMVCで述べたような処理を行うのはProxy、MediatorとView Component、Commandと呼ばれるプログラムたちです。コアアクターの仕事はこれらを自分に登録し、管理することです。もちろん登録はFacade経由で行います。コアアクタークラスの仕事をまとめると、次のようになります。

  • ・Model … Proxyを登録(Facade経由)し、管理する
  • ・View  … Mediatorを登録(Facade経由)し、管理する
  • ・Controller … Commandを登録(Facade経由)し、管理する

また、Proxy、MediatorおよびView Component、Commandの役割は次のようになります。

  • ・Proxy … Modelクラスに登録され、サーバとのやり取り、データの管理、ビジネスロジックを担当
  • ・Mediator … Viewクラスに登録され、View Componentの管理、Notificationの送受信を担当
    • ・View Component … Mediatorに登録され、ユーザの入力の受け取りと見た目の処理を担当
  • ・Command … Controllerクラスに登録され、Notificationに応じてProxyを呼び出す

MediatorがViewクラスに管理されてさらにView Componentを管理しているというややこしい構造になっていますが、これについては次回説明したいと思います。

また、ここで初めて出てきたNotificationはイベントにも似た概念なのですが、これについても次回説明したいと思います。

ちなみに、Proxy、Mediator、View Component、Commandにあたるプログラムは当然たくさん必要になってきますが、それらを管理するコアアクタークラス、つまりModelクラス、Viewクラス、Controllerクラスはそれらを管理する大元の存在なのでインスタンスが一つしか必要ありません。Facadeクラスもです。よってコアアクターとFacade(を継承したクラス)のインスタンスはプログラムにただ一つだけ存在し、利用されます。このような「プログラム中に一つしかインスタンスがない」ことを保証するデザインパターンのことを「シングルトンパターン」といいます。また、私が参考にしたサイト(http://translated.by/you/puremvc-implementation-idioms-and-best-practices/into-ja/ (404 Not Found))では「プログラム中に一つしかインスタンスがない」ことを指して「シングルトン」と呼んでいるので、以降はそのような意味で用いることとします。

それでは次回をお楽しみに。

スマートフォン最適化に便利な【weinre】を使ってみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


お久しぶりのwryyyです。

今流行?のスマートフォン最適化サイトを作る際、

スマートフォン実機でサイトを確認したら、デザインが崩れてる!!!となった場合、
皆様はどうしているでしょうか?

・実機だと、FireFoxのFirebugなんて便利なもの使えないし…

・気合を入れて修正しては確認して…ってのもめんどくせー!!!

ってなった時にはもう大変です。

さて、そんな時にオススメするのが今回ご紹介する

weinre

です!

さて、ではまず【weinre】とは何かから入って行きましょう。

weinreとは、簡単に行ってしまえばスマートフォンで閲覧しているページの
・HTML DOM
・CSS
・Javascript
等をPCから確認できるようにしちゃおうっていうツールです。

では、実際にインストールと使用方法について説明していきます。

※ 私のPC環境がMACのため、MACの手順で記載させて頂きます

1. ダウンロード

まずは https://github.com/phonegap/weinre/archives/master ここから

weinre-jar-1.5.0.zip
(mac OSX 10.6 Snow Leoperd 以上の方は weinre-mac-1.5.0.zip)
をダウンロードします。

※ weinre-mac-1.5.0.zip の中身は weinre をパッケージ化したものが入ってます。

2. 解凍

weinre-jar-1.5.0.zip(weinre-mac-1.5.0.zip) を解凍しましょう。

3. 設定ファイルの作成

自分のユーザのホームディレクトリ配下 「.weinre」というディレクトリを作成し、
.weinre 配下にserver.properties というファイルを作成します。

% pwd
/Users/username
% mkdir .weinre
% vim .weinre/server.properties

.weinre/server.properties の中身は以下のようになります。

% cat .weinre/server.properties
boundHost:    -all-
httpPort:     8081 

※ 設定の詳細は http://phonegap.github.com/weinre/Running.html を御覧ください。

4. 実行

・weinre-jar-1.5.0.zip を解凍した場合

% export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
% java -jar weinre-jar/weinre.jar --boundHost 192.168.3.181

上記コマンドでweinreが起動されます。

※ weinre-jar を実行するには Java 6.0 が必要なので、
事前にexport してJava のバージョンを変えておく。

・weinre-mac-1.5.0.zipを解凍した場合

解凍したディレクトリに出来ている、weinre をダブルクリック

5. 確認

ブラウザから http://[IPアドレス]:[ポート番号] に接続します。

(アドレスは –boundHost 、ポート番号は server.properties で設定したもの)

すると、weinreのページが閲覧できるはずです。

閲覧できたら、「debug client user interface」のリンクをクリックしておいてください。

リンクを押すとchromeのデベロッパーツールのようなページが出ます。

Targets が none になっているはずです。

次はスマートフォンの操作です。

スマートフォンでブラウザから適当なサイト(https://www.google.co.jp/ とか)にアクセスしてください。

アクセスしたら「bookmarklet url in a textarea」と書かれているテキストフィールド

に入力されているJavaScript をなんとかコピーし、

スマートフォンブラウザのURL入力欄に貼りつけて実行してください。

(事前にスマートフォンで http://[IPアドレス]:[ポート番号] に接続し、テキストフィールドに入力されているJavaScript をコピーしてブックマークに登録しておくと次回からブックマークをクリックするだけで利用できるので便利です!)

貼りつけて実行しましたら、元にアクセスしていたページに戻るはずです。

ここで、さきほどPCでクリックしておいたページを見てみましょう。

Targets が緑色で

「192.168.2.83 [channel: 1200079761 id: anonymous] – https://www.google.co.jp/ 」

と表示され、Clients も緑色で表示されるようになりました!

では、上部タブの Elements をクリックしてみてください。

Chrome のデベロッパーツールのように HTML の DOM が表示されたでしょうか。

Chrome のデベロッパーツールのように、DOM 上にマウスを合わせたら、
なんとスマートフォンの画面もその DOM に当たる部分が薄い灰色っぽく反転します!

これでいろいろテストすることが可能になります。

※ いろいろ試した結果、どうもページ遷移は対応していないようで
ページ遷移する毎に weinre の JavaScript を実行させないとダメないようです。

以上がweinreの解説と実行方法になります!
※ 上記実行手順等はコチラを参考にさせていただきました。

※※ 上記サイトによると、呼び方は 「ワイナリー」 もしくは 「ワイナー」 らしいです。

   weinreを説明しているyoutubeの外人さんは「ウィ…ナー?HAHAHA」って言ってました…

是非、利用して快適なスマートフォン最適化サイト開発をお送りください!

rubyでミリ秒までの時間生成方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

「20120509104004229」、「2012-05-09T10:40:04.229Z」
のようなミリ秒までの時間文字列を時間に変換して、計算をしたいことがあります。
簡単ですが、ミリ秒までの時間オブジェクトの生成方法をご紹介します。■ruby1.8.7では下記の書き方です
>> time = Time.utc(2012, 5, 9, 10, 40, 4, 229*1000)
=> Wed May 09 10:40:04 UTC 2012
>> time.iso8601(3)
=> “2012-05-09T10:40:04.229Z”

>> time  = Time.local(2012, 5, 9, 10, 40, 4, 229*1000)
=> Wed May 09 10:40:04 +0900 2012
>> time.iso8601(3)
=> “2012-05-09T10:40:04.229+09:00”

>> time2  = Time.local(2012, 5, 9, 10, 40, 5, 300*1000)
=> Wed May 09 10:40:05 +0900 2012
>> time2 – time
=> 1.071

■ruby-1.9

ruby-1.9では、「to_r」という文字列を有理数に変換するメソッドも使えます。

ruby-1.9.2-p180 :004 > time = Time.utc(2012, 5, 9, 10, 40, 4, 229*1000)
 => 2012-05-09 10:40:04 UTC
ruby-1.9.2-p180 :005 > time.iso8601(3)
 => “2012-05-09T10:40:04.229Z”
ruby-1.9.2-p180 :006 > time.iso8601(6)
 => “2012-05-09T10:40:04.229000Z”

ruby-1.9.2-p180 :007 > time = Time.utc(2012, 5, 9, 10, 40, “4.229”.to_r)
 => 2012-05-09 10:40:04 UTC
ruby-1.9.2-p180 :008 > time.iso8601(6)
 => “2012-05-09T10:40:04.229000Z”
ruby-1.9.2-p180 :009 > time.iso8601(3)
 => “2012-05-09T10:40:04.229Z”

ちなにみ、ruby1.8.7では、
>> time = Time.utc(2012, 5, 9, 10, 40, “4.229”.to_r)
NoMethodError: undefined method `to_r’ for “4.229”:String
        from (irb):34
        from :0

絶対に笑ってはいけないRSpecの現場24時

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、SHIMADAです。 今日は現場の泥臭いRSpec話を書きます。

新しいフィーチャーを追加するとき、specがなかなか通らない、実装が思い通りに進まない、ということがありますよね。
そんなとき、自分の書いたコードが実際にはどう動いているのか確かめる方法が欲しいです。

一番簡単で広く使われているのはデバッグプリントという手法です。
コードの中に p 変数名 と書くと、specの実行途中にその変数の中身がどうなっているか確認できます。

ここで問題になるのが、specがたくさん書いてあるとデバッグプリントが一杯出てきて肝心の調べたいケースが埋もれてしまうという点です。

ちなみに今携わっているプロジェクトのspecを見てみると、examplesの数が1,000を超えてました。

これが一般的な水準で多いのか少ないのか分かりませんが、ここまできてしまうとデバッグプリントがどかどかっと表示されてあっという間に押し流されてしまうので大変です。

そういう状況でもなんとかしようと編み出した泥臭いテクニックを以下に紹介します。

説明のために簡単なバグ入りのコードと、それを検出するテストを用意しました。

コード


class Calculator
  attr_reader :answer

  def plus(a, b)
    @answer = a + a
  end
end

テスト


describe Calculator do
  subject do
    Calculator.new
  end

  it "1 + 1 = 2" do
    subject.plus(1, 1)
    subject.answer.should == 2
  end

  it "2 + 2 = 4" do
    subject.plus(2, 2)
    subject.answer.should == 4
  end

  it "2 + 3 = 5" do
    subject.plus(2, 3)
    subject.answer.should == 5
  end
end

こんな感じでコードとテストを書いたとします。
バグがあるので “2 + 3 = 5” は成功しません。

Calculator#plusにデバッグプリントを埋め込んで、引数と計算結果を調べてみましょう。


  def plus(a, b)
p :chk1
puts "b = #{b.inspect}"
puts "b = #{b.inspect}"
    @answer = a + a
  end

まず、デバッグ用のコードは通常のコードではないことを強調するために、インデントを無視して行頭から書くようにしています。
こうすることでデバッグが終わってコミットする前に、無駄なコードを消し忘れることを防ぎます。

それから、先頭の p :chk1 は僕が個人的に使っているデバッグ用のマーカーです。
RSpecはピリオドがたくさん出力されます。
デバッグ出力が行の途中から始まると折り返しが読みにくいので、:chk1という目印を使って強制的に改行します。


..........:chk1
a = 1
b = 1
......

当然、いろんなところにデバッグプリントを入れていくときは :chk1, :chk2, :chk3… と数字を増やしていきます。

ところで、このままだと全部のテストケースでデバッグプリントが出力されてしまいます。
できれば、失敗するspecの時だけデバッグプリントを出力したいですね。
そこで、specの側に一時的にこういうものを埋め込みます。


  it "2 + 3 = 5" do
$dbg=true
    subject.plus(2, 3)
$dbg=false
    subject.answer.should == 5
  end

はい。ご覧のとおり $dbg は禁断のグローバル変数です。
グローバルなのでspec内で定義して本番コードの中から参照できます。無敵です。

ちなみにコミットする前に除去する一時的なコードなので、この変数は本来のコードと被らなければどんな名前でも構いません。

使い方は、Cでよくある


#define DEBUG


#ifdef DEBUG

のペアと同じです。


  def plus(a, b)
p :chk1 if $dbg
puts "b = #{b.inspect}" if $dbg
puts "b = #{b.inspect}" if $dbg
    @answer = a + a
  end

これで、調べたいテストケースの時だけデバッグプリントを出力させることができるようになりました。
特定のケースで、どの行でどんな挙動が起こっているか確認できると、デバッグはかなり捗ります。

あとそれから、デバッグプリントだけでは足りなくてどうしてもうまくいかない難しいケースのとき、


debugger if $dbg

としたこともあります。specの実行中この箇所に到達すると、Rubyのデバッガが起動するのでステップ、トレースしながらコードを追いかけてなんとか問題を解決することができました。

最後に、コードのバグがとれてspecが通るようになったらこれらは全部消してきれいにしてからコミットします。

タネを明かせばどうっていうこともない簡単なことですが、なかなか役に立つので今までずっと使っています。みなさんもバグに手こずった時、試してみることをお薦めします。

Android UnitTest

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Androidアプリのテストコードを書いてみました。
今回は画面遷移に関するテストコードです。

事前にunitテストの環境を準備する必要があります。

下記などを参考にさせて頂きました。

http://www.yaunix.com/2011/01/08/android%E3%81%A7%E3%81%AEunittest%E3%81%AE%E5%A7%8B%E3%82%81%E6%96%B9/ (410 Gone)

 Activityコード

public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout contentView = getContentView();
        setContentView(contentView);
    }
    
    private LinearLayout getContentView() {
        LinearLayout l = new LinearLayout(this);
        Button button = new Button(this);
        button.setText("ターゲットへ遷移するボタン");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClassName(getApplicationContext(), TargetActivity.class.getName());
                startActivity(intent);
            }
        });
        l.addView(button);
        return l;
    }

}

 テストコード

/**
 * 
 * ActivityInstrumentationTestCase2を継承したクラスを作成する 
* テストするクラスを指定する(MainActivity) * */ public class MainActivityTest extends ActivityInstrumentationTestCase2<mainactivity> { /** * 次の画面へ遷移するためのボタン */ private Button button; /** * コンストラクタ * テストするクラスを指定する(MainActivity) */ public MainActivityTest() { super("MainActivityTest",MainActivity.class); } /** * テスト前の準備 */ @Override protected void setUp() throws Exception { super.setUp(); /** * Buttonを取得しておく */ button = (Button) getActivity().findViewById(1); } public void testOnClick() { getActivity().runOnUiThread(new Runnable() { @Override public void run() { /** * 遷移先のクラスをMonitorにセットする */ ActivityMonitor monitor = new ActivityMonitor(TargetActivity.class.getName(), null, true); getInstrumentation().addMonitor(monitor); /** * Buttonをクリックする * (押せることもテストしておく) */ assertTrue(button.performClick()); /** * 画面遷移したあとのクラスを取得する */ Activity next = getInstrumentation().waitForMonitorWithTimeout(monitor, 10); /** * Monitorでセットしたクラスと画面遷移したクラスが同じことを検証する */ assertEquals(monitor.getHits(), 1); if ( next != null ) { /** *遷移した画面を閉じる */ next.finish(); } } }); } }

次は画面遷移以外のテストコードも投稿できればと思ってます。

参考になれば幸いです。

カテゴリで既存メソッドを拡張しようとすると表示されるwarningの対応

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近はiPhoneアプリ開発をさせてもらっているのですが、
いつからか(下記参考リンクによるとXcode4.3かららしいですが)、カテゴリを利用して既存クラスの既存メソッドを拡張(上書き)しようとすると


"category is implementing a method which will also be implemented by its primary class"

というwarningメッセージが表示されるようになりました。

やはりwarningメッセージを出しっぱなしだと気持ち悪いので、表示させない方法を調べたところ


#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

// 拡張したいメソッドを記述

#pragma clang diagnostic pop

と #pragmaで囲むと表示されなくなります。

参考サイト

guard-shellでファイル監視

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 概要

  • メモ取りにはSphinxがおすすめ
  • ファイル変更監視に使えるRuby GemとしてGuardがある
  • ファイル変更検知時にシェルコマンドを使いたい場合,guard-shellというgemを使う

 メモとりにはSphinxがおすすめ

 はじめまして,Ruby厨のわたなべ(hackugyo)です.

 ところでみなさんはPythonって知っていますか.最近では「グーグル独自のプログラム言語」などと新聞にも紹介されて話題の言語です(<=はい,ここ笑うところですよ).

 Pythonのコードは見た目がきれいに整うという特徴がありますよね.Rubyはコードブロックをdo-endで表現するのに対し,Pythonはインデントで表現するからです.Rubyはend地獄(Pythonはthis地獄)とはよく言われます.

 私はRuby厨ですので,インデントでブロックを表現するのにはぜんぜん慣れられないのですが,そんな私でもインデントのうまみを思い知ることがあります.

 それはテキストメモをとるときです.

典型的なテキストメモ

 業務中,私たちはコードを書いているばかりでなく,RedmineにToDoを切り出したり,Skypeチャットで議論をしたりと,いろいろ文字をうちます.特に私などは,書き出さないと考えがまったく整理できないので,ローカルのメモにも大量の書き込みをしています(大半は「うううこのコードがうまくいかない」「あああおれがばかだった」などです).

 以前は,これをwiki記法で書いていましたが,するとEmacs上での見た目はこういうふうになります:

* 2012/04/18(水)
** 今日のToDo
- コードレビュー依頼
-- 日取り・メンバを決める
** 今日取り組んでいる問題
- URL取得がうまくいかない
-- このメソッドが悪いのか?
 SuperComplexActivity # getUrlAndParseAndMakeQuery()
-- どう考えても切り分けが必要

 内容はともかく見づらいですね.

Sphinxによる見やすいテキストメモ

ここでPython流の,インデントによる構造化を取り入れてみたらどうでしょうか.

================
2012/04/18(水)
================

今日のToDo
==========

- コードレビュー依頼

  - 日取り・メンバを決める

今日取り組んでいる問題
===================

- URL取得がうまくいかない

  - このメソッドが悪いのか?


.. code-block:: java

 SuperComplexActivity # getUrlAndParseAndMakeQuery()

- どう考えてもメソッド分割が必要

見やすいですね!

 じつは上記の記法はreST記法といって,Python製のドキュメンテーションツールSphinxで読むことができます.Sphinxのよいところは,テキストファイルの状態でも上記のようにそこそこ読みやすいreST記法を扱っており,さらにそのテキストファイルをビルドすることで,HTMLやPDFなど見栄えのする形式に変換できることです.

 私も,Emacsで上記のようにメモをとったあと,`make html`のシェルコマンドにより,Wikiのような形式に変換しています.過去のメモの参照がしやすく,気分もよくなります.

 ファイル変更検知にはGuard

 さて,前節で述べたような「メモをとる=>保存する=>コマンドを叩く」の流れは,明らかに自動化すべきです.保存をかけたらそれだけでhtmlができあがっていれば便利ですね.

 ここからが本題です.「ファイル編集=>保存する=>処理実行」と言えば,Ruby厨として思い出すのは当然,Guardです.Guardは,RSpecによるテスト実行時に使うRubyGemとして有名な,ファイル変更監視ツールです.Guardを使うことで,Railsのモデルを編集しただけで自動的にRSpecを実行するなどの処理が簡単に行えます.

 Guardを,上記のようなテキストメモの監視&コマンド実行にも使えないでしょうか? もちろんできます.やってみましょう.

(もちろん,ファイル変更監視ツールは他にもいろいろあります.Rubyにもwatchrというgemがありますし,Pythonならwatchdogがあります.シェルスクリプトを組んでポーリングしてもいいでしょう.エディタがEmacsなら保存時にフックして処理を挟む手もあります.今回はRuby厨として,Guardの使い方を広げるために,Guardを使います.)

shell操作にはguard-shell

guardにシェルコマンドを叩かせるには,guard-shellというgemが必要です.

$ gem install guard-shell

これだけでGuard込みでインストールできます.逆に,Guardだけでやろうとするとうまくいきません(私はこれで1時間はまりました.下記のGuardfileにでてくるシンボル:shellをGuardに理解させるには,guard-shellが必要です.).

 インストールできたら,監視対象とするディレクトリまで移動し,下記のようなGuardfileを置きます.

# -*- coding: utf-8 -*-
guard :shell do
  watch( %r{(.*)¥.rst} ) { |m| `echo #{m.first}が更新されました` }
end

rstは,reST記法を使って書かれたドキュメントによく使われる拡張子です.上記の例では,ディレクトリ直下の*.rstファイルの変更をすべて監視させ,変更があるたびに,更新されたファイル名をechoするシェルコマンドを叩かせています.簡単ですね.

 echoの代わりに,Sphinxのコマンドmake htmlを叩かせるようにすれば,要求が実現できます.

あとは,

$ guard

のコマンドを叩くだけで,Guardが自動的にGuardfileを読み込み,ファイル更新検知をはじめてくれます.

これでテキストメモ保存時のひと手間が減りました.Guardであなたの貴重な時間を守りましょう.

 ご参考

  1. reST記法については,こちらのチュートリアルが親切です:http://sphinx-users.jp/doc11/rest.html
  2. Sphinxについては,
    • 同じくSphinx-Users.jpを参照するか,
    • 株式会社ビープラウド, *Pythonプロフェッショナルプログラミング*(秀和システム, 2012)なども勉強になります.
  3. Guardはこちらにソースがあります. https://github.com/guard/guard-shell
  4. Guard-Shellなど,Guardと組み合わせて使えるgemのリストはこちらです. https://github.com/guard/guard/wiki/List-of-available-Guards

モットときVim

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回はXcode4ユーザーに唾涎もののプラグインの紹介です。

そのプラグインとは「XVim」。

説明しなくとも分かるとは思いますが、Xcode上でVim操作を実現したプラグインです。

XVim – https://github.com/JugglerShu/XVim

このプラグインがあれば、外部エディタとしてVimを起動する必要もなく、

Xcodeの補完をはじめ様々な機能がフルに使えちゃいます。

インストール方法は簡単、ソースをダウンロードしてきてXcodeでビルドするだけで、

Xcodeのプラグインフォルダにインストールされます。

あとはXcodeを再起動すると…キャー!見慣れたステータスバーが−!

ちなみにパッケージでも提供されているようですが、

ソースからの方が最新の機能など使えるのでオススメです。

(※デイリービルドも公開されているようです)

こちらのプラグイン、hjklに始まる基本的なキーバインドだけではなく、

  • ・検索/置換
  • ・Visual
  • ・TextObject
  • ・キーマッピング
  • ・.xvimrc

などなど機能も豊富。

まだまだ、動作は不安定で、たまにXcodeごとクラッシュしますが、

Vimの機能が使える方がメリットが大きいので全然気になりません。

作者は日本の方で、開発も精力的に行われているようです。

iPhone開発者でVim好きな方は、是非1度このプラグインを試してみてください。

AndroidのScrollViewでスクロールの位置が変わったのを取得する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

AndroidのListViewでスクロールの位置が変わったのを取得する際は、ListViewにOnScrollListenerをセットしてあげれば取得することができます。

ならScrollViewでも同じようにOnScrollListenerをセットすれば、スクロールの位置が変わったのを取得できる、、と思いきやそうもいきません。

ScrollViewの場合は、ScrollViewを継承してスクロールの位置が変わったのを取得できるScrollViewを作ります。

public class ObservableScrollView extends ScrollView {
    
    public interface ScrollViewListener {
        void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
    }
    
    private HorizontalScrollViewListener scrollViewListener = null;

    public ObservableHorizontalScrollView(Context context) {
        super(context);
    }
    
    public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public ObservableHorizontalScrollView(Context context, AttributeSet attrs, int defs) {
        super(context, attrs, defs);
    }
    
    public void setOnScrollViewListener(HorizontalScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }
}

ポイントは、Activityなどのスクロールの位置が変わったのを伝えるためのInterfaceを用意するのと、

それを onScrollChanged(int x, int y, int oldx, int oldy)の中に組み込むことです。

ちなみにiPhoneならUIScrollViewのDelegateをセットすれば、- (void)scrollViewDidScroll:(UIScrollView *)scrollViewでスクロールの位置が変わったのを取得できます。

なんて、面倒くさいのでしょう!

Ruby on Rails Rails2からRails3へ移行後の色々

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


rick No25です。
今回は、Rails2からRails3へ移行後発生したバグなどを何個か紹介。

rails2の環境

ruby 1.9.1
rails 2.3.11

rails3の環境

ruby 1.9.3
rails 3.0.7

incompatible character encodings: UTF-8 and ASCII-8BI

DB(ASCII-8BI)からview(UTF8)に表示するときにこのエラーが発生します。
解決法
「force_encoding(‘UTF-8’)」の使用
使用例
@user.name.force_encoding(‘UTF-8’)

NoMethodError: private method `readline’

ファイルをアップロードするときにこのエラーが発生します。
解決法
「tempfile.__getobj__」の使用
使用例
params[:file].tempfile.__getobj__

puts delete時の挙動

ログイン系のサイトでputsやdeleteなどを使用してリンクを押下したところ
なぜかログアウトしてしまう事象が発生。
getにはhiddenにauthenticity_tokenが設定されるが、
putsやdeleteには設定されていなかった模様。
解決法
「form_authenticity_token」の使用
使用例
link_to hoge_path(削除したいitem, :authenticity_token => form_authenticity_token), {:method => :delete}

文字参照

xmlを送信したところ文字が文字参照になっていた。
これは以前からなっていて対処もconfig/initializers以下に置いてあったが、 Rails3になってから読み込む順番が変わったのか読み込まれなくなった。
解決法
cinfig/initializersのファイル内で「rack/content_length」を読み込む
使用例
require ‘rack/content_length’

メールがtext形式

html形式のメールを送っていたがtext形式になってしまい、
タグが表示されるようになってしまった。
解決法・使用例
「ActionMailer::Base.default_content_type=”text/html”」をapplication.rbに追加

エラー時メール送信

エラー時にメールが送信されなくなった。

解決法
オーバーライドメソッドの変更
使用例
def log_error(exception)

def rescue_with_handler(exception)

ruby on railsのfindについてメモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ruby on railsのfindで取得できる値を列挙してみます。

条件に一致するものが見つからない場合に、それぞれ返却される値が違ったりするのでその確認用の記事です。

(検証環境:rails 2.3.11)

Hogehoge.find(:all) またはHogehoge.all

  Hogehogeクラスオブジェクトがレコード分の配列で返却されます
    [#<hogehoge id: 1, column1:0>, #<hogehoge id: 2, column1:1>, #<hogehoge id: 3, column1:0>]

  条件に一致するものが見つからない場合(レコードが0件の場合):[](空配列)

Hogehoge.find(:first) またはHogehoge.first

  最初のレコードが1件のみ返却されます
    #<hogehoge id: 1, column1:0>

  条件に一致するものが見つからない場合:nil

Hogehoge.find(1)

  プライマリキーが1のHogehogeクラスオブジェクトが返却されます
    #<hogehoge id: 1, column1:0>

  条件に一致するものが見つからない場合:例外

Hogehoge.find_by_column1(0)

  カラム名column1が0という条件に一致する最初のレコードが1件のみ返却されます
    #<hogehoge id: 1, column1:0>

  条件に一致するものが見つからない場合:nil

ゲーム機材の不思議(インターネットに何が送信されてるの?)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、インターネットに接続することを前提としたモバイル端末が各種存在しているが、今回はそうしたモバイル端末がどのような通信を行なっているかに着目してみよう。

今回取り上げるモバイル端末は、次の2種類だ。

・Nintendo 3DS

・PS Vita

 Nintendo 3DSの場合

Nintendo 3DSは、「いつの間にか通信」と呼ばれる機能があり、端末をスリープさせている間に通信を行い、動画ファイルや各種アップデートなどをダウンロードし、ユーザが利用しようと立ち上げた時に、そうした情報を告知する機能だ。では、具体的に通信内容をみてみよう。

下線1のように、定期的にkeep Aliveの通信を行い、接続を常に維持している。そして、下線2の時間になると、データを一気にダウンロードしている事がわかる。また、通信先は常に conntest.nintendowifi.net となっており、米国の任天堂に接続をしているようだ。

この時、サーバに転送している情報が以下となる。

GET / HTTP/1.1

Host: conntest.nintendowifi.net

User-Agent: CTR AC/02

HTTP_X_GAMEID: 00002400

Content-Type: application/x-www-form-urlencoded

Connection: Close

ここに、HTTP_X_GAMEID とあるのが読めるだろうか。このIDを利用することでバージョン情報やどういったゲームなのか等、本体の情報を通知していると思われる。

さて、こうした情報を通信している3DSだが、ゲームを購入する場合、下記通信を行なっている。

GET /ccs/download/0004000000045C00/00000000 HTTP/1.1

Host: ccs.cdn.c.shop.nintendowifi.net

Connection: Keep-Alive

先程のキープアライブ時は、接続先が conntest.nintendowifi.net であったのに対し、アプリを購入する場合、ccs.cdn.c.shop.nintendowifi.netに接続していることがわかる。また、FQDNより、CDN(コンテンツデリバリーネットワーク)を利用していることも想像できる。

 PS Vitaの場合

PS Vitaの場合は、起動しネットワークに接続した際、下記情報を取得する。

http://fjp01.psp2.update.playstation.net/update/psp2/list/jp/psp2-updatelist.xml?ver=01520000&sid=e57cd5a9658dab1ffcbfb174b6b49906b42d1f210cd6eb5fafa6ea358030a61d&nd=0

この情報は、ファームウェアの状態を確認し、ファームウェアの更新が必要であるかを起動時にチェックするようになっている。

より、具体的に見ていこう。

まず、上記のURLをリクエストするとき、上記のURLに現在のバージョンらしき情報も送っていることに気づくだろうか。

ver=01520000 だ。この時のリクエストでは、本体のバージョンが、1.52であることを示している。このバージョン情報を書き換えても、帰ってくる情報に変更はない。おそらく、iOSの時と同じように、Vitaに於ける国勢調査的なものだろう。

さて、リクエストした結果、psp2-updatelist.xml がダウンロードされてくる。その中には、下記の情報が含まれている。

<np level0_system_version=”01.600.000″ level1_system_version=”01.610.000″ level2_system_version=”01.610.000″ map=”00.000.000″ />

この情報は、現在の最新版が何であるかを示している。また、最新版の情報以外にも、

<recovery spkg_type=”systemdata”>

<image spkg_version=”01.000.010″ size=”56821248″>

や、

<recovery spkg_type=”preinst”>

<image spkg_version=”01.000.000″ size=”128841216″>

といった情報も含まれている。この情報を見るとわかるように、PS Vita内部では、ファームウェアとしてsystemdataと呼ばれる部分が存在していることがわかる。また、万一システムのアップデートに失敗した際、エマージェンシーモードで起動し、上記2つを強制ダウンロードすることで、システムを復旧させることができると推測される。

 カスタムファームフェイク画面を作ってみる

上記では、ファームウェアのバージョン情報をXMLが持っている事がわかった。では、この情報を書き換えて、強制的にVitaに流しこむと何が起きるだろうか。

まずは、次のものを用意する。

1.毎度おなじみのフェイクDNS

2.上記DNSの結果を反映するネットワーク

3.カスタムファームウェアを配布するサーバ

まず、1だが、どんなリクエストをおこなっても、必ず特定のIPアドレスを返す、魔法のDNSを用意する。この時、fjp01.psp2.update.playstation.net に対する答えをはじめ、常に一定のIPアドレスを内部に返答してくれる。次に、上記IPアドレスを模したネットワークを用意する。単純に、VM Wareで構築するのがいいだろう。

先ほど構築したVM Ware 上に、どのようなリクエストをされても、常にpsp2-updatelist.xml を返事するサーバを構築しよう。あとは、先ほどの

<np level0_system_version=”01.600.000″ level1_system_version=”01.610.000″ level2_system_version=”01.610.000″ map=”00.000.000″ />

の、01.600.000 を、「KBMJ Custum Edition」等のように、好きな値に書き換えよう。こうすると、PS Vita上にはそのとおりの画面が表示される。スクショを撮影し、友達に見せびらかそう。きっと驚いてくれることに違いない。

ただし、そこの表示されているファームウェア情報は、あくまでもフェイク。実在しないし、実際にファームウェアを更新することはできない。十分注意しよう

SSL証明書ペア確認コマンド

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。にゃんです。

ものぐささんにぴったりなちょっと便利な、 opensslコマンドに関して記載します。

秘密鍵とCSR作成し、CSRを認証局に提出して、証明書が発行された後に、どの鍵か不安になってしまったり、念の為合致しているか確認したい場合ってないですか?

そんな時は、以下のコマンドでペアが正しいか確認する事ができます。

#openssl x509 -noout -modulus -in server.crt | openssl md5

12345678abcdefg12345678abcdefg

#openssl rsa -noout -modulus -in server.key | openssl md5

12345678abcdefg12345678abcdefg

#openssl req -noout -modulus -in server.csr | openssl md5

12345678abcdefg12345678abcdefg

表示される結果が同じであれば、同じペアです。(=導入可能です。)

もし、表示される結果が違うのであれば、一生懸命どこかに保存したペアを探しましょう。

証明書情報を表示させたい場合は、以下ので表示させる事が可能です。

 #openssl x509 -in server.crt -text(証明書も含めて表示)

 #openssl x509 -noout -text -in server.crt(証明書を除いて表示)

上記の結果は、証明書の情報が全て表示されてしまいます。

期限だけを確認したい場合は

#openssl x509 -in server.crt -noout -dates

ディスティングイッシュネームを確認したい場合は

#openssl x509 -in server.crt -noout -subject

とする事で、表示される事が出来ます。

新卒入社時に読んでおいたら捗ったかもしれないもの2選

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


3月も後半に入り、卒業式シーズンまっさかりですね。この春からこの業界に入られる新卒の皆様、入社(予定)おめでとうございます。

というわけで、新卒で入社する前、入社した後あたりに読んでおいたら捗るかもしれないものをご紹介できればと思います。

対象としては以下のような方を想定しています。

  • ウェブサイトの開発を行う会社で技術系の職種に就く予定
  • これからする仕事の内容について未経験
  • 下手するとプログラミング等も未経験

学校やアルバイト、あるいは個人でモリモリ開発業務みたいなことやってましたというかたや、きちんと情報系の学問を勉強してきましたというかたにとっては、おそらく既知の情報かと思います。文系でプログラミングなども未経験というかたには、少し役に立つかもしれません(自分がそうだったので、あのころ読んでおいたら捗ったかもしれない、というものをあげています)。

 目次

  • しごとでつくる領域のこと
  • しごとでつかう領域のこと

 しごとでつくる領域のこと

読んでおいたら捗ったかもしれないもの

理由

特定の言語やフレームワークによらない、ウェブアプリケーション開発に必要な情報が満載です。HTTP についての基本的な内容はためになります。Rails で強く推されている REST についてもわかりやすく書かれており Rails での開発に役立つこと請け合いです。

Rails などのフレームワークを利用して開発すると、HTTP の仕様についてあまり意識せずに機能を実現できます。「その機能でやりたいことだけを考えて作業できる」ので、とても生産性が高いです。なので、HTTP の仕様について知識がなくても開発をすすめることができますが、知らなくていいというわけではありません。

たとえば以下のようなバグは、本当に基本的なことを知っていれば防げるようなことですが、何も考えずに作業しているとうっかり仕込んでしまうかもしれません。

  • アクセスするたびにカートに物が増える(許容される場合もあるかもしれません)
  • クローラがリンクをたどったらリソースが消えた
  • リンクを踏んだら「こんにちはこんにちは」という記事が書かれた

Rails などのフレームワークを利用して HTTP についてあまり意識せず機能を実現できる、というのは、もうすこし正確に言うと、「その機能でやりたいことを、周囲のいろいろなことから切り離して考えて作業できる」です。なので HTTP についての基本的な内容を知っておくと、バグや脆弱性の少ないウェブサイトを実現できて、捗ります!

 しごとでつかう領域のこと

読んでおいたら捗ったかもしれないもの

理由

この業界では、おそらく、開発環境は Linux や Mac などの Unix 的なもので行う可能性が高いです。Windows で開発をするとしても、.NET なので本番サーバも Windows です、というようなケースを除けば、本番は Linux の OS がのったホストでアプリケーションが動いている、という可能性が高いはずです。

なので、どこかしらで Linux 環境に触れる機会がでてくると思います。ディレクトリの移動や、ファイルの一覧を見る、ファイルの中身を見る、ということはできてあたりまえになっておくと捗ります。

また、ちゃんと基本的なことを知っておけば「なんかアプリケーションがログ吐けずに死にます、バグってるようなので、調査します」→「よくみたらディレクトリの権限がおかしかったみたいです」というような凡ミスに気付く確率があがり捗ります。

なにより、普段自分が普段作業するときに、ストレスなく作業できるようになっていれば、間違いなく捗ります。このテキストはかなりボリュームがあり挫折しそうになるかもしれませんが(自分は挫折しました)、読めば読んだだけためになると思います。

開発環境については、自分が普段つかう(つかおうと思っている)エディタや IDE についても、基本的なこととヘルプの引きかたを覚えるだけで捗り度はアップします。vim については、日本語のヘルプをひけるようにしておくと、より捗るかもしれません。

なお、設定にこだわりすぎたり、エディタ議論に絡むのは楽しいかもしれませんが、あまり捗らないのでほどほどにしておくといいと思います。

 次のステップ

基本的なことを知ったら、こんどはインフラやセキュリティ、品質を上げる知識などを学んでいくといいかもしれません。 「データベース技術[実践]入門」は「サーバインフラ本」「徳丸本」と並ぶウェブエンジニア必携の教科書 – As a Futurist… などを参考にされるとよいかと思います。

以上、ヒヨッコながらも、先輩風を吹かせてみましたが、だれかのお役に立てば幸いです。

新卒の皆さんが、楽しく捗りライフを送られることをお祈りいたします。

maven1.0.2インストーラ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

いつの頃からかMaven 1.0.2がMacPortsからインストールできなくなっていたので、作成したインストーラを公開します。maven 1.0.2 を自分のプロジェクトで使っているのですが、2012-03-19現在、MacPortsからはインストールができなくなっています。一見、以下のようにインストールできそうな気がするのですが


% port search maven
maven @1.0.2 (java, devel)
    stub port, use maven1 instead

maven-ant-tasks @2.1.3 (devel, java)
    Use many of Maven's artifact handling features from Ant.

maven1 @1.1 (java, devel)
    A java-based build and project management environment.

maven2 @2.2.1 (java, devel)
    A java-based build and project management environment.

maven3 @3.0.4 (java, devel)
    A java-based build and project management environment.

maven_select @0.3 (sysutils)
    common files for selecting default Maven version

Found 6 ports.

一見インストールできそうですが、


% sudo port install maven 
Password:
--->  Configuring maven
Error: maven is a stub, use maven1 instead.
Error: Target org.macports.configure returned: obsolete port
Log for maven is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_java_maven/maven/main.log
Error: Status 1 encountered during processing.
To report a bug, see 

maven1使って、と言われてしまいます。しかしながらmaven1.0.xとmaven1.1.xはモノが違いますし、困るプロジェクトが世の中にはまだある…という事でインストーラを公開しました。

maven 1.0.2

/opt/local/bin/mavenとしてインストールされます。

Ruby on Rails Rails3コマンド 〜よく使うコマンド〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No24です。
今回は、Rails3のコマンドを簡単に紹介。

環境

ruby 1.9.3
rails 3.0.7

アプリ作成

rails2まで
$ rails hoge
rails3から
$ rails new hoge

コントローラー等作成

rails2まで
$ ruby script/generate controller hoge index
rails3から
$ rails generate controller hoge index

migrate

rails2まで
$ rake db:migrate
rails3から
$ rake db:migrate
変化なし

サーバ起動

rails2まで
$ ruby script/server
rails3から
$ rails s

コンソール

rails2まで
$ ruby script/console
rails3から
rails c

その他

$ bundle install
Gemfileの中身をinstallします。
installした内容は
$ bundle exec list
で確認完了
実行するときは
$ bundel exec rails s
このように先頭に「bundle exec」を付けてください。

前はrailsコマンドでアプリ作成だったので今回から
railsコマンドはサーバ起動とかあるためなんだか違和感ありますが、
慣れるしかないですね。

利用規約の解釈

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

昨今、様々なサービスが展開されているが、サービスを利用するに当たり、利用規約が掲げられている。今回は、利用規約のなかから「あれ?」と思わせるような内容をいくつか、ピックアップしてみよう。

 どこからか持ってきた規約

いくつかの規約で、共通する文言を目にする事がある。そういった文言を、googleに入れ検索すると、大量に同じような規約が登場する。当然、元の規約*1があるわけだが、それを探そうにも、どれがマスターだったのか解らない状況に。

 電気通信事業法?

SNSの利用規約に見られるモノとして、[電気通信事業法(昭和59年法律第86号)第4条に基づき,利用者の通信の秘密を守る]と書かれたモノがあるが、そもそも、電気通信事業法は、「電気通信事業者」に対する法律であり、電気通信事業者を取得していない者は関係ない法律だ。

電気通信事業者では無いにもかかわらず、こうした事を掲げる場合、詐称もしくは詐欺行為と見なされる場合がある。注意が必要だ。

 電気通信事業者?

もうひとつの問題もある。それは、何らかの利益を得ての役務が発生している場合だ。

通常、電気通信事業者は、第三者を経由する通信を「有償」で提供している場合に取得する必要のある資格だ。友達から施設負担金として、月額数百円レベルでお金をもらっていても、この資格は必要であるし、また、アフィリエイトなどの広告を掲載している場合も、同様の資格が必要となる。当然として、出会い系サイトなどを運営する場合も、同様の資格が必要となる。過去の事例としては、国内のみにサービス提供しているゲームで、海外の利用者を、国内のproxy経由でアクセスできるようにしていた、中国人留学生が検挙されたが、これも、きっかけは電気通信事業者の資格を有していなかった事に端を発している。こうしたサービスを提供する際には、電気通信事業者の資格取得を、忘れないよう、注意されたい。

 インターネットの仕組みを理解していない

[サービスに関わる記載について,無断でそのコピー,複製,アップロード,掲示,伝送又は配布等をする行為]と書かれたモノを多く見る。が、コンピュータやインターネットでは、多くの情報を「常に複製」し、画面に表示したり音にしている。たとえ、マウスやキーボードで入力したデータであったとしても、メモリやCPU、その他のIOデバイスを経由するなかで「すべて複製」したものであり、どれ一つとして「オリジナル」と呼べるモノは無い。そういった中で、こうした規約は「あぁ、コンピュータやインターネットの仕組みを理解していないんだな」と、考えざるを得ない。本来、こうした規約は、本や雑誌などの物理内容について、作られたモノと推測されるが、そのまま、ネットのサービス規約に持ってくるのが、そもそも間違いと言えよう。

*1: 規約そのものに対しては著作権法の適用対象外なので、複製しても問題は無い

CentOS6でnode.jsをrpmからinstallする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rails 3.1ではJavaScriptのランタイムが必要になります。

今回はCentOS6にnode.jsを入れて対応してみます。

標準でRails3.1をインストールするとassetsという仕組みでCoffeeScriptが利用されることになります。

そのため、JavaScriptのランタイムがないと起動できません。

$ rails s -p 5001
/usr/local/lib/ruby/gems/1.9.1/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47
:in `autodetect': Could not find a JavaScript runtime. 
See https://github.com/sstephenson/execjs 
for a list of available runtimes. (ExecJS::RuntimeUnavailable)
(以下略)

実際、Gemfileに指定されているcoffee-railsは以下のような依存関係があります。

$ gem dependency coffee-rails
Gem coffee-rails-3.1.1
  coffee-script (>= 2.2.0)
  railties (~> 3.1.0)

$ gem dependency coffee-script
Gem coffee-script-2.2.0
  coffee-script-source (>= 0)
  execjs (>= 0)

では、この依存関係をクリアするようにCentOS上でnode.jsをインストールしましょう。

ただし、普通にソースコードから入れてしまうと管理のコストが上がってしまい非常にSAN値が削られてしまうので、Redhat系OSらしくrpmでインストールしましょう。

運がいいことに、kazuhisyaさんがspecファイルを公開しているので、こちらを利用します。

ちなみに、ruby1.9をインストールしたときにだいたい依存関係クリアしていたっぽいので、ビルドで落ちたら依存関係を確認してください。(yum-builddepとか使ったことないので…)

$ mkdir -p ~/rpmbuild/SOURCES/
$ cd ~/rpmbuild/SOURCES/
$ wget http://nodejs.org/dist/v0.6.5/node-v0.6.5.tar.gz
$ cd
$ git clone https://github.com/kazuhisya/nodejs-rpm.git
$ cd nodejs-rpm/
$ git checkout -b v0.6.5 v0.6.5
$ rpmbuild -bb nodejs.spec
$ sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/nodejs-0.6.5-1.el6.x86_64.rpm

これでnode.jsのインストールが完了しました。

あとはサーバを起動してみましょう。

$ rails s -p 5001=> Booting WEBrick
=> Rails 3.1.3 application starting in development on http://0.0.0.0:5001
=> Call with -d to detach
=> Ctrl-C to shutdown server

無事成功しました。

大変有益なspecファイルを公開してくれたkazuhisyaさん、ありがとうございます!今度おごってください!

ソーシャルメディアとの付き合い方

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

昨今、ソーシャルメディアを使った様々なサービスがあるが、今回はソーシャルメディアを使うことによるメリットとデメリット(リスク)について考えてみたいと思う。

 ソーシャルメディアを企業が利用するメリット

今、Twitterやmixi、facebookなどといった、様々なソーシャルメディアが存在する。このソーシャルメディアを用いた、各種割引クーポンサービスや、ソーシャルゲーム*1などの情報提供サイトが多数存在している。これらの情報提供サイトは、従来のサイトと異なり、極めて少ないコストで広告を提供している。これは、利用者が告知することにより、利用していない人に対しても、告知が広がるためであり、企業は多くの友人や知人を持つユーザに対し、情報を提供するだけでよく、従来の広告モデルより安価に広告費を減らすことが出来る。

 ユーザがソーシャルメディアを利用するメリット

一方、ユーザはソーシャルメディアを利用することで、10数年ぶりに友人とソーシャルメディア上で再会したり、遠くにいる人とチャットで情報交換する等のメリットが有る。また、企業が提供する各種クーポン等を安価に手に入れることができ、今までとは違った情報の入手ルートを開拓することが出来る。他者の書いた記事を読むことで、今まで思いもしなかった様な情報を定入れたり、他者の意見交換をすることで、新たな考え方を共有することが出来る。

 ユーザがソーシャルメディアを利用することのリスク

こうした情報交換をすることで、様々な情報を手に入れられる一方、自ら発信する情報には気をつける必要がある。自分を見つけやすくするために、出身校や住んでいる地域、スカイプIDやメールアドレス等といった情報を公開することが有る。こうした行為は、自分を見つけ出しやすくするだけではなく、攻撃者により多くの情報を与えることになり、結果としてなりすましメールや標的型メールが送りつけられる事になりかねない。

 標的型攻撃のシナリオ

たとえば、◎◎銀行に勤めるA氏にターゲットを絞ったと仮定する。普通に、A氏に対して標的型メールを送ったとしても、開いてもらうことさえままならないだろう。そこで、登場するのがソーシャルメディアだ。まず、A氏のアカウントを調べることから始める。Facebookでは、本名を書くことが規約に書かれているため、A氏にたどり着くことは容易いだろう。A氏のアカウントを見つけたら、A氏と親しく会話している人を数名見つけよう。ここで、重要なのは見つけるのは複数人であることだ。一人しか見つからなかった場合、ソーシャルメディアを用いた攻撃は諦めたほうが良い。

A氏と親しい人を数名見つけたら、次にその人を含む多くの人たちと、友人になろう。その時、決して素性をばらすようなことはやめることだ。自然にダミーデータを散りばめ、決して本名や個人情報を晒さないようにする。万一、疑われても本人に警察の魔の手が及ばないようにする。A氏に近づくために、A氏と親しい友人たちと知り合いという「担保」を用い、A氏に友人申請をしよう。A氏がよほど疑り深い人で無い限り、A氏の知ってる「友人たちも知ってる」という「担保」によって、A氏は容易に攻撃者からの申請を受け入れるはずだ。

もし、A氏の親しい知人が一人しかいなかった場合、A氏は攻撃者からの申請を疑ったかもしれないし、その親しい知人に、問い合わせていたかもしれない。

A氏の友人として、まんまと潜り込めたら、次はA氏と全く関係のない人たちに、どんどん友人関係を築き、多くの人と友人関係にあることをA氏にそれとなく、アピールしよう。こうすれば、自分を狙っているようには思わないだろう。

A氏と友人たちの、ウォールでの会話は、攻撃者も見ることができるだろう。この会話をよく読み、今何を会話しているのか。それぞれ、共通の興味を調べておこう。その時、会話に登場する友人の個人情報も調べておくことを忘れないでほしい。共通の話題や趣味、個人情報をある程度把握したら、友人になりすまして、A氏にメールを送る。その時の文面はこうだ

「先日、Facebookで話したゲームだけど、新しい情報見つけたよ。よかったら見て、Facebookで感想を送って」と。

メールに添付するURLは、ながければ長いほどよい。下手に短縮URLを使うと、Facebookやツイッターじゃないのになぜ?と、不審がられるだろう。

そのURLに、標的型ウィルスを仕込んでおけば、そのサイトをクリックした瞬間にウィルスの餌食になる。単純なアンチウィルスでは、感染したウィルスのシグニチャを持っていないため、駆除することはできない。もちろん、Facebookで偽装した本物の友人に確認しても、後の祭りだ。

実際には、こんなに簡単に標的型ウィルスを感染させることは難しいだろうが、時を重ねて会話の内容をほぼすべて把握すれば、こうしたことも難しくないかもしれない。

 現在地を示すソーシャルアプリ

今、ソーシャルメディアは多様化しており、現在地を示すツールも、ロケタッチや4sqなど多数存在する。現在地を示し、待ち合わせをするには、十分だと思うが、そこに居るということは、他の場所(例えば自宅や会社など)にはいないということになる。一人暮らしの場合、それをツイッターやFacebookなどで他人に対してまで公開することは、空き巣に入って欲しいと言っているようなものだ。こうしたツールを使うなら、相手を限定し、決して第三者に情報を開示しないことだ。

ソーシャルメディアで、なりすましを避けるには、一番良いのはソーシャルメディアを使わないことだが、どうしても使いたい場合は、明らかに個人を特定しうる以上の情報を提供しないことだ。顔写真や本名、連絡先、電話番号など多彩になればなるほど、攻撃者からも特定され安くなることを肝に銘じてほしい。また、自分が知らないけど、共通の知人がいる人から友人登録の申し込みがあった場合、そのまま登録するのではなく、共通の知人の中でも「リアルに連絡先を知っている知人」に連絡を複数取り、「この人ってどんなひと?」と聞くのが確実だろう。もし、「よく知らないんだけど」や「ネットで最近知ってね」という人が、複数出た場合は、要注意として、ペンディグしたほうが良いだろう。承認はあとでもできるし、場合によっては、そのまま無視することも出来る。一度、友人登録を許可してしまったら、登録解除まで、情報が流れてしまうことを理解しておこう。多くの情報を集約し、巨大化するソーシャルメディア。実際に使うときは、十分情報管理には注意したほうが良いだろう。

*1: 弊社も提供している

CERT Oracle Java セキュアコーディングスタンダードをAndroidアプリケーション開発へのルールの適用に合わせてソートしてついでにリンクをつけてみた。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Android開発者が必要なのがどれなのか破滅的にわかりづらいのでとりあえずソートしてみた。

JPCERT/CCCERT Oracle Java セキュアコーディングスタンダード 日本語版を公開しております。

その中で、Androidアプリケーション開発へのルールの適用という項目があるのですが、順番が項目順で破滅的に分かりづらいので、Android開発でガリガリ下がりまくったSAN値を回復するためにソートしなおしてrubyでリンクもつけて見ました。

以下が、その表になります。リンク間違ってたらTwitterのsmellmanに適当にMention送ってください。

ルール評価コメント
IDS07-JA
IDS09-JA
EXP00-JA
NUM02-JA
MET00-JA
MET02-JAAndroid SDKにもdeprecatedやobsoleteなAPIが存在する
MET04-JA
MET05-JA
MET12-JA
ERR02-JA
ERR07-JA
ERR08-JA
VNA00-JA
VNA02-JA
LCK01-JA
LCK02-JA
LCK06-JA
FIO03-JA
FIO05-JA
FIO08-JA
SER01-JA
SER03-JA
SER08-JA
SEC03-JAAndroidではDexClassLoaderやPathClassLoaderの使い方に気をつける必要がある
SEC05-JAリフレクションを使うと非公開のAPIにアクセスすることができるので気を付ける必要がある
ENV02-JAコード例にあるuser.nameはAndroidでは使われないので空になっているが、環境変数という仕組みはもちろんAndroidにも存在するので当てはまる
MSC00-JA
MSC02-JA
MSC03-JA
IDS00-JBコード例ではMS SQL Serverを使った接続例を示しているが、AndroidではSQLiteのDatabaseHelperクラスを使ってDBにアクセスする。
EXP02-JB
EXP03-JB
EXP04-JB
NUM09-JB
NUM10-JB
NUM11-JB
MET06-JB
LCK03-JB
TSM03-JB
SER05-JB
SER11-JB
IDS01-JC
IDS03-JC
IDS11-JC
MET01-JCAndroidでassertを使う場合は、adb shell setprop debug.assert 1かdalvikvm -ea
MET03-JCコード例で使われているSystem.getSecurityManager(); はAndroidでは使われていない。コードの互換性のために存在。
LCK08-JC
FIO14-JCAndroidでは、Activity#finish(), Activity#moveTaskToBack(boolean flag), android.os.Process.killProcess(ind pid), System.exit()
SER04-JC
SEC00-JC
SEC01-JC
SEC02-JC
SEC04-JC
SEC06-JC
SEC07-JC
ENV00-JCAndroidでのコード署名は、開発者の識別、アプリケーション間の信頼関係を確立するため
ENV01-JC
ENV03-JC
ENV04-JCdalvikvm -Xverify:all とかで設定できる
ENV05-JC

作成は、エクセルにコピペしてCSV作成してnkfかましたあとのファイルをこんなスクリプトでサクッと。出力は安心のはてな記法です。

require 'csv'

open("jpcertlist_utf8.csv") do |file|
  file.each_with_index do |aline, idx|
    line = CSV.parse_line(aline)
    if idx == 0
      puts "|*#{line[0].to_s.strip}|*#{line[1].to_s.strip}|*#{line[2].to_s.strip}|"
    else
      url = "https://www.jpcert.or.jp/java-rules/" + line[0].strip.downcase + ".html"
      puts "|[#{url}:title=#{line[0].to_s.strip}]|#{line[1].to_s.strip}|#{line[2].to_s.strip}|"
    end
  end
end

しかし、SJISですらSAN値下がりますね>エクセル

RubyでAmazon S3のマルチパートアップロードを利用する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 yoppiです。今回はRubyでAmazon S3のマルチパートアップロードを行う方法を紹介させていただこうと思います。

 Amazon S3のストレージシステムをAPIで利用する場合、ファイルアップロードを1回のリクエストで行うことは、ファイルのサイズが大きくなるにつれて失敗の確率が大きくなります。

 そのリスクを回避するための機能がマルチパートアップロードです。詳細は下記のリンクを参照していただくことにして、簡単に説明するとファイルを小分けにして、複数回のリクエストでアップロードできるというものです。

【AWS発表】 Amazon S3において大容量ファイルを分割アップロード可能にするマルチパートアップロード機能(Multipart Upload)の発表 – Amazon Web Services ブログ

 便利である分、APIの仕様が複雑になっているのですが、Ruby用のSDKでは(他の言語用も多分そうでしょうが)難しい仕様は隠ぺいする形で実装されているので、便利な機能が簡単に使えるようになっています。

 SDKはgemで提供されているので、簡単に導入できます。

gem install aws-sdk 

 以下に利用例のコードを紹介します。

require 'aws-sdk'
AWS.config(
  :access_key_id => 'YOUR_ACCESS_KEY_ID',
  :secret_access_key => 'YOUR_SECRET_ACCESS_KEY')

file_path_for_multipart_upload = 'SOME_FILE_PATH'

#前もってSOME_BUCKET_NAMEという名前のバケットを作成する必要がある
bucket = AWS::S3.new.buckets['SOME_BUCKET_NAME']

open(file_path_for_multipart_upload) do |file|
  uploading_object = bucket.objects[File.basename(file.path)]
  uploading_object.multipart_upload do |upload|
    while !file.eof?
      upload.add_part(file.read 10.megabytes) 
      p('Aborted') if upload.aborted?
    end
  end
end

 AWS::S3::S3Objectのインスタンスを生成し、multipart_uploadに引数1つのブロックを渡し実行します。

 渡したブロックの引数にAWS::S3::MultipartUploadのインスタンスが渡されるので、それのadd_partに小分けにしたファイルの内容を渡す。

 大まかには以上のようになります。

 マルチパートアップロードでも失敗する場合はあり、それはAWS::S3::MultipartUploadのインスタンスのaborted?で判別でき、その値を元に再送など必要な処理を実装することができます。

 Amazon S3を使うRubyシステムを扱う場合、大きなファイルのアップロード処理が必要になることもあると思います。

 その時に是非この内容を参考に指定ただければと思います。

最近人気な記事