まどか、Blu-ray購入

しました。

今劇場でやってるやつもいずれ出たら買います。これは何度か繰り返し観ると、味わいが変わってくるはず。

かぐや姫はなあ… 媒体買おうと思わないや。もしかすると10年とかたった後に観たくなるのかもしれないけど。いまはまだ、その時じゃない。

かぐや姫の物語を観てきた

観てきました。うん、なんというか、キレイだったし、姫の表情・感情もよく描けていたし伝わってきたし、翁はどうしようもないバカだけど、媼と一緒に姫を愛していたし、姫の愛する世界は美しかった。歌も素晴らしかったですよ。iTunesで買いましたし。

でも、なんか、それだけだったなあと。

贅沢なことを言っているんだと思う。どっかで「風立ちぬ」が制作費100億なんて話を鈴木PがしているのをTVか何かで見た記憶があるんだけど、「かぐや姫の物語」だって製作期間は長いんだし、3/4ぐらいは使ってそうだ。そんだけのリソースをぶっこんで、という事を考えると、なんか伝統芸能保存会の作った日本昔話のスペシャル版としか思えない。

一方で、はるかに費用対効果の高い作品を昨日観ちゃってるんですよ。なんか、ジブリはアートと伝統芸能の保存というところにしか生き残る道はないような気がしてきました。パンツ御大が復活とか、相当事態を憂慮しての事なのかもね。

魔法少女まどか☆マギカ 叛逆の物語、観てきた

ついさっき観てきました。ちょっと感想など。ネタバレてんので、それがアレな人はそっとどこかにいってくれるといいなと。

映画全体を観ての印象だけど、なんというか、いろいろな味わいの料理が並んだフルコースを楽しんできた感じ。それぞれの料理ごとに味わいが変わってくる。そして最後に出てきたフロマージュが人を選ぶ独特の香り(臭気かもしれない)があって、でも、口に含めばそれはそれでおいしいよと、そんな感じの流れだった。

やはり主役はほむらちゃんなんだけど、なんか、切ないな。大好きで大好きで、大切にしてきたお友達を、自分ともども壊すほど思いつめて。多分そのための時間は、数えきれない繰り返しの中で十分すぎるほど積み重ねてきたにしても、その思いはあまりにも重すぎる。そしてそれが人の愛だという答えも。

最後にはそれが神様と悪魔を生じて、その二人が手を取り合ってゆく世界というのは、現し世はこうあって欲しいという作り手の願いのようにも思った。悪魔を生ずるのが愛ではなく、神様と悪魔も結びつけるのが愛だよと。

一方で、やはり強く印象に残ったのは、度しがたきが人の欲という事でもある。愛という言葉で語られたけれども、本当の意味での愛ではないよね。そこは、ほむらちゃんの欲でさ。まあ、狂ってしまうのに十分すぎるほどの時間を過ぎてのことではあるし、そこまで追い詰められれば、人は変わってしまう、狂ってしまうものなんだよって事なんだけどさ。まあ、いろいろと難しい。だからこそ、この世界はもめ事が絶えないわけなんだけど。

2/3ぐらいまではね、すごく甘い展開で、文字通りみんなの願いがかなったような世界でさ。あのままキレイに終わる事もできたはずだけど、そうならなかった。それを残念と思うんだけど、そこで終わらせるような人々なら、こんなここまでの作品は作れなかったよなーとも思う。なんかね、ここも難しい。すっぱーんと明快に割り切れる評価ができない。そーゆー、難しさ満載の作品だった。

難しい難しいって連発してるけど、単純なところではさやかちゃんの立ち位置がよかったな。魔女になっても、別に終わりでもなんでもなく、世界の一部としてきちんと存在していたというのがうれしかった。

なーんか、とりとめなくなっちゃったな! ひさびさの感想日記だからしょーがない。しかもなかなか感想書くのが難しいネタだし! もういいや、とりあえず俺はこう思ったよ! 送信!

昨日のコードちょっと修正

昨日書いたコード、ちょっと修正してみた。元の記事の「いかがだろう、ずいぶんとすっきり記述できる。」という所に少しでも近づきたいという気持ちがあって、いや、あのIfブロックはあれはあれで、ハッキリとした意思表示だと思うんだけど、もっとスパっとかけないもんかなーと。

で、Queueなら! と思いついて利用箇所をこう変えた。

        'こんな風に書けるよ!
        Dim hogeParam1 As String = "hogedefault1"   'set default
        Dim hogeParam2 As String = "hogedefault2"   'set default
        If opts.ContainsKey("hoge") Then
            With opts("hoge")
                hogeParam1 = If(.Count > 0, .Dequeue, "hogedefault1")
                hogeParam2 = If(.Count > 0, .Dequeue, "hogedefault2")
            End With
        End If

見た目はだいぶマシになった。先方のサンプルにあるportとrootを取る記述にしてみる。

        Dim myOptions() As String = {"root", "port"}
        Dim opts = (New OptionParser(myOptions, "-"c)).Parse(args)

        'こんな風に書けるよ!
        Dim root As String
        If opts.ContainsKey("root") Then
            root = If(opts("root").Count > 0, opts("root").Dequeue, ".")
        End If

        Dim port As Integer
        If opts.ContainsKey("port") Then
            If Not Integer.TryParse(If(opts("port").Count > 0, opts("port").Dequeue, "80"), port) Then
                port = 80
            End If
        End If

実際の利用場面を想定したコードだと、それほどのスッキリ感はないなあ。でも、If式でデフォルト値とセットで書けるのはだいぶコンパクトにまとめられるようになったと思う。横に長くなるけども。
あと整数値を取るときの型変換がダルイなー。一気にみてくれがわるくなった。でもまあ、こんなもんじゃないかな。過剰に美しさを求めると、他が犠牲になったりするし、ここでやめとこう。

そうそう、パーサクラスはこうなった。

Public Class OptionParser
    Private listOfOptionName As New List(Of String)
    Private swChar As Char
    Public Sub New(ByVal args() As String, ByVal swc As Char)
        swChar = swc
        listOfOptionName = args.Distinct().ToList()
    End Sub
    Public Function Parse(ByVal args() As String) As Dictionary(Of String, Queue(Of String))
        Parse = New Dictionary(Of String, Queue(Of String))
        For i = 0 To args.Length - 1
            Dim targetArg = args(i)
            If listOfOptionName.Exists(Function(n) String.Format("{0}{1}", swChar, n) = targetArg) Then
                Parse.Add(targetArg.Remove(0, 1), New Queue(Of String))
            Else
                If Parse.Count > 0 AndAlso targetArg(0) <> swChar Then
                    Parse.Last.Value.Enqueue(targetArg)
                Else
                    Debug.Print("{0} droped.index={1}", targetArg, i)
                End If
            End If
        Next
    End Function
End Class

DictionaryのValueがQueueになっただけ。ああ、あとSubstringをRemoveに変更。こんな便利関数があるなんて、今でもVB6現役のボクは知りませんでした!

VB2008でコマンドライン スイッチの判定を実装してみた

http://devadjust.exblog.jp/20069155/
この記事を見て、久々に何か書いてみたいな!と思ったので、書いてみます。

まず、コマンドライン引数のパーサを書くんだけど、パースした結果をどう扱えるか? どれだけ扱いやすいか? という事から考えてみた。私なら、こう書きたい。

        Dim opts = (New OptionParser).Parse(args)   'この辺はきっとごにょごにょする

        Dim hogeParam1 As String = "hogedefault1"   'set default
        Dim hogeParam2 As String = "hogedefault2"   'set default
        If opts.ContainsKey("hoge") Then            'こんな感じで「このパラメータあれば」って書けるとうれしい
            With opts("hoge")                       'VB風味を加える
                If .Count >= 1 Then                 '個別の引数はこんな感じで
                    hogeParam1 = .Item(0)
                End If
                If .Count >= 2 Then
                    hogeParam2 = .Item(1)
                End If
            End With
        End If

こんな感じでスイッチの部分はディクショナリのキーになってて、そのスイッチの引数はディクショナリの値(コレクション)に要素として入ってる。きっと書くときこうなってると嬉しい感じがする。で、これをやってくれるOptionParserを書いた。

Public Class OptionParser
    Private listOfOptionName As New List(Of String)
    Private swChar As Char
    Public Sub New(ByVal args() As String, ByVal swc As Char)
        swChar = swc
        listOfOptionName = args.Distinct().ToList()
    End Sub
    Public Function Parse(ByVal args() As String) As Dictionary(Of String, List(Of String))
        Parse = New Dictionary(Of String, List(Of String))
        For i = 0 To args.Length - 1
            Dim targetArg = args(i)
            If listOfOptionName.Exists(Function(n) String.Format("{0}{1}", swChar, n) = targetArg) Then
                Parse.Add(targetArg.Substring(1, targetArg.Length - 1), New List(Of String))
            Else
                If Parse.Count > 0 AndAlso targetArg(0) <> swChar Then
                    Parse.Last.Value.Add(targetArg)
                Else
                    Debug.Print("{0} droped.index={1}", targetArg, i)
                End If
            End If
        Next
    End Function
End Class

呼ぶときはこんな感じに。

    Sub Main(ByVal args() As String)
        Dim myOptions() As String = {"hoge", "fuga", "piyo"}
        Dim opts = (New OptionParser(myOptions, "-"c)).Parse(args)

コンストラクタの第二引数に"-"cとか書いてあるのは、ほら、あれですよ、スイッチって"/"のコマンドとかもあるじゃないですか。そこらへんのフィーリングに引数ひとつで対応する為。考えすぎかもしれないけど。

呼び出し部分全体を、もっかい貼り付けてみよう。

Module OptionParseSample
    Sub Main(ByVal args() As String)
        Dim myOptions() As String = {"hoge", "hoge", "fuga", "piyo"}
        Dim opts = (New OptionParser(myOptions, "-"c)).Parse(args)

        'パースした結果を出力
        For Each item In opts
            Console.WriteLine(item.Key)
            For Each p In item.Value
                Console.WriteLine("  {0}", p)
            Next
        Next

        'こんな風に書けるよ!
        Dim hogeParam1 As String = "hogedefault1"   'set default
        Dim hogeParam2 As String = "hogedefault2"   'set default
        If opts.ContainsKey("hoge") Then
            With opts("hoge")
                If .Count >= 1 Then
                    hogeParam1 = .Item(0)
                End If
                If .Count >= 2 Then
                    hogeParam2 = .Item(1)
                End If
            End With
        End If
    End Sub
End Module

お楽しみでほいほいーっと書いたので、テキトーにバグってるかもしんない(予防線)。でもまあ、OKだ。初めてGitHubリポジトリも作ってアップしちゃったー! きゃー!w

でも、このリポジトリへのリンクとかどうやって貼るんだろ? ま、それはあとで勉強しよう。ひとまず送信!