コーディングを支える技術、読んだ

流行りの技術や特定の言語によらないプログラミングの学び方を学ぶ本。構成がよく考えられていて首尾一貫しているので自然に頭に入ってくるし楽しく読むことができた。少し感想を書きたい。

名前というものがある

名前を使う前までは番号を使ってたんだけど、人間は番号だけ見ても何のことかわからないしすぐ忘れちゃう。だから番号に対応するオブジェクトに名前をつけてあげたらわかりやすくて便利になった。とても便利でよかったんだけど、名前とオブジェクト対応表が一つだけだと、うっかり同じ名前を使ってしまうと競合して壊れるから注意して憶えておく必要がある。人間は無意識に記憶を改竄したりするし、ずっと対応表について思いを馳せていることはできない。じゃあどうしたかというとそこでスコープというものが産まれた。

こんな感じで人がいろいろ工夫して言語が進化していく過程が書かれている。普段考えもしない細部にも歴史がある。

多重継承に対する言語間の違い

多重継承には複数の親クラスの間で同じ名前のメソッドがあったとき、どちらを優先するかという問題がある。僕はc#メインで使っているので、多重継承禁止*1するのがすっきりしてていいと思ってた。でも果敢にも多重継承できるようにしちゃって、やっぱり結構苦労していたりする言語とか、moduleのみmix-inを可能にしたrubyとか、scalaなんかは初期からtraitがあったりする。それぞれの言語の実装の違いが簡潔にまとめられていてとてもわかりやすいと思った。

コラム

コラムがいくつかあって、その中でも

  • 理解を確認するためにはまずアウトプット
  • 何を学べがよいかがわからない理由
  • 具体的な知識と抽象的な知識
  • 噛み砕く
  • 必要なところからかじる
  • おおまかにつかんで徐々に詳細化する
  • 端から順番に写経する

このあたりなんだけど、なかなかこういう技術の学び方って文章化されにくいし、初心者の人はこのコラムだけ読んでもかなり参考になると思う。

僕は去年、応用情報技術者試験を受けていたのだけれど、その試験用に勉強した、こういうものがある、そういうものもある、みたいな広く薄い知識に、歴史という重みを与えてくれたのがこの本だった。海苔だけだったのに海苔に餅が包まれて質量あるし砂糖醤油で食べると美味しいみたいな感じです。もっと早く読めばよかった。

こちらに補足記事が載っているので全部読みましょう。

*1:interface除く

httpまたはhttpsでのアクセスを強制するカスタムフィルター

httpsでしかアクセスさせたくないページの場合、そのページのアクションメソッドに [RequireHttps]属性を付けると、httpでアクセスしたとき自動時にhttpsにリダイレクトさせることができます。

でもその逆、httpsでアクセスしたときにhttpにリダイレクトさせるような属性は用意されていません。なので自分で作る必要があります。

これ既に作っていた人がいて、それがこちらの記事。消えちゃってるのでInternetArchiveとGistの直リンク。

このカスタムフィルター属性結構良いと思うのですが、2点おしいところがあります。

  1. SSLSSLページで異なるドメイン*1やポートを使用している場合対応できない*2
  2. クエリストリングやアンカー(#)を引き継いでリダイレクトできない*3

1は開発サイトとかでありがち。

その辺を考慮して少し修正した対応版作りました。

using System.Web.Mvc;
 
namespace Utils.Filter
{
    public enum Scheme
    {
        Ignore,
        Http,
        Https,
    }
 
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class RequireHttpSchemeAttribute
        : FilterAttribute, IAuthorizationFilter
    {
        private readonly Scheme scheme;
 
        public RequireHttpSchemeAttribute(Scheme scheme)
        {
            this.scheme = scheme;
        }
 
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if ((scheme == Scheme.Https) && !filterContext.HttpContext.Request.IsSecureConnection)
            {
                filterContext.Result = GetResult(filterContext, "https://localhost:1443");
            }
            else if ((scheme == Scheme.Http) && filterContext.HttpContext.Request.IsSecureConnection)
            {
                filterContext.Result = GetResult(filterContext, "http://localhost:1180");
            }
        }
 
        private static RedirectResult GetResult(AuthorizationContext filterContext, string baseUrl)
        {
            var uri = new Uri(baseUrl);
 
            return new RedirectResult(uri.GetLeftPart(UriPartial.Authority) + filterContext.HttpContext.Request.RawUrl);
        }
    }
}

URLベタ書きの部分は普通はWeb.configとかに記述してあると思うからそれを使いましょう。

使い方

こんな感じです。

[RequireHttpScheme(Scheme.Http)]
public virtual ActionResult HttpOnly()
{
    return View();
}

これはhttpsでアクセスされた場合、httpにリダイレクトする。

[RequireHttpScheme(Scheme.Https)]
public virtual ActionResult HttpsOnly()
{
    return View();
}

これはhttpでアクセスされた場合、httpsにリダイレクトする。

[RequireHttpScheme(Scheme.Https)]
public class AlmostSecureController : Controller
{
    public virtual ActionResult HttpsOnly()
    {
        return View();
    }

    [RequireHttpScheme(Scheme.Ignore)]
    public virtual ActionResult DoesntMatter()
    {
        return View();
    }
}

これはコントローラー自体に属性が付いていますので、このコントローラー内の全てのアクションメソッドでhttpsでのアクセスを強制しようとしています。しかし例外として特定のアクションメソッドにはリダイレクト処理をさせたくないという場合があります。
そういうときに例外にしたいアクションメソッドにScheme.Ignoreを設定したRequireHttpScheme属性を付けてあげると、そのアクションメソッドでは何も起きなくなります。*4 一つのコントローラー内に沢山アクションメソッドがある場合に便利かもしれませんね。

*1:IPも

*2:これはRequireHttps属性も対応してない

*3:UrlBuilder.Pathにクエリストリング以下を設定するとランタイムエラーになる

*4:でもこういう場合は往々にしてこのメソッドだけhttpアクセスを強制させたかったりするので、Scheme.IgnoreじゃなくてScheme.httpを設定することになると思う

はてなブログのテーマを作っていたらgruntでlessをコンパイルする環境ができていた

  1. はてなブログboilerplateが公開されている
  2. このboilerplateにはコンパイル前のlessとコンパイル後のcssが含まれている
  3. どうせならlessで書いてコンパイルしたい
  4. gruntを使えばlessファイルの保存を検知して自動コンパイルするタスクが組める
  5. gruntを使うにはnode.jsのパッケージ管理ツールnpmが必要
  6. nodebrewならnode.jsのバージョンも管理できる

ということなので、はてなブログのテーマを作ろうとしたら何故かnodebrewのインストールから始めることになった。

nodebrewのインストール

この辺り読んで入れた。僕はnodebrew installしてしまったけど、nodebrew install-binaryにしたほうが速いしいいと思う。
知らずにnodebrew installしたら大変時間が掛かってたいへん大変だった。

gruntのインストール

Web制作で面倒な作業を自動化するビルドツール、Grunt v0.4 入門|Web Design KOJIKA17

このへん。プラグインについては、まずgruntを入れて

npm install grunt --save-dev

lessをコンパイルする grunt-contrib-less

npm install grunt-contrib-less --save-dev

ファイルを監視して何かをする grunt-este-watch

npm install grunt-este-watch --save-dev

サーバーに繋いでLiveReloadする grunt-contrib-connect を入れた。

npm install grunt-contrib-connect --save-dev

grunt-contrib-watchではなくてgrunt-este-watchにしたのは軽いから。

Node.js - grunt-este-watchとgrunt-contrib-connectで軽快ファイル監視とLiveReload - Qiita [キータ]

Gruntfile.js作成

grunt-contrib-lessでlessファイルのコンパイルを自動化する。 - タチコマ好きなエンジニアのブログ

この辺りを参考にさせてもらった。僕のGruntfile.jsはこちら

grunt-contrib-lessの設定は、開発環境用と

development: {
    options: {
        paths: '<%= less.production.options.paths %>'
    },
    files: {
        '<%= projectName %>.css': '<%= projectName %>.less'        
    } 
}

clean-cssで圧縮してcss出力する本番環境用に分けた。

production: {
    options: {
        paths: ['less'],
        cleancss: true
    },
    files: {
        '<%= projectName %>.min.css': '<%= projectName %>.less'        
    }
},

pathsは開発/本番どちらも同じにしたいので、開発は本番のプロパティ値を参照するようにした。cssはプロジェクトのルートに出力するようにした。

ちなみに<%= %>はgruntのテンプレート機能で、自分で定義したものを使ったり、他のプロパティから参照したり、jsをインラインで実行できたりする。詳しくはここ

grunt-este-watchについては、

esteWatch: {
    options: {
        dirs: ['./', 'less/'],
    },
    'less': function(filepath) { return 'less:development' }
}

カレントディレクトリとlessディレクトリのlessファイルに更新があれば、grunt-contrib-lessの開発環境用タスクが動くという感じ。

そしてgrunt-contrib-connectは、

connect: {
    server: {
        options: {
            livereload: true,
            port: 9000,
            open: 'http://localhost:<%= connect.server.options.port %>/view/'
        }
    }
},

こんな感じでlivereload: trueにしておくと、grunt実行時にLiveReloadに必要なスクリプトをhtmlファイルに自動でインジェクトしてくれる。これをやっておけばブラウザのLiveReloadエクステンションとかはいらない。あとopenにURLを指定することでデフォルトのブラウザを使って自動でそのページを開いてくれるようになる。/view/以下にテスト用のindex.htmlなどをおいているのでそこを指定。

CSSコンパイル

あとはプロジェクトのルートで

grunt

を実行すればターミナルが待機状態になり勝手にブラウザでview/index.htmlが開く。そしてlessファイルを修正すると自動でコンパイルしてブラウザ再読み込みが走る。これはたのしい。

貼り付け

良い塩梅にデザインできたら

grunt less:production

で圧縮して出力されたcssはてなブログのデザインCSSに貼り付けておしまい。css出力先をdropboxとかにしてはてなブログ側で外部css読み込みしておけば一々コピペとかしなくて捗ると思う。

はてなブログテーマのらくちん制作環境 - kyabana's blog

でも僕は様々なしがらみがあってやっていない。人間誰しもしがらみを持って生きているからしかたがないことだと思う。

ソースはGitHubに置いておいた。

distkloc/SankakuValidator

Xamarin StudioでNuGetを使う

blogを書くのは久しぶりなので、簡単なことを簡単に書くことにした。
今回は.NETのためのパッケージマネージャNuGetをXamarin Studioで使う方法について書いてみる。

続きを読む