トップ 最新 追記

日々の破片

著作一覧

2022-06-05

_ Object#as_jsonとObject#to_json

以下のようなオブジェクトモデル、クラスAの集合とクラスAのインスタンスをJSON化することを考える(Rails環境)。重要なのはAクラスが自分を保持するオブジェクトへの参照を持つことだ。

class A
  def initialize(caption, data, parent)
    @caption = caption
    @data = data
    @parent = parent
  end
  attr_reader :caption, :data
end
 
class ACloud
  def initialize(items)
    @items = items.map {|e| A.new(e[0], e[1], self)}
  end
  attr_reader :items
end
 
list = ACloud.new([[:a, 0], [:b, 1]])
puts list.to_json       # stack level too deep (SystemStackError)

bundle exec rails r test.rbを行うとスタック深過ぎエラーとなる。まあ、そうなるよね、という結果だ。

ここで自分を保有するオブジェクトへの参照を持つのは実装の都合なので(Aのインスタンスを単体で扱う場合があり、そこから親を取得する必要があるとする)、JSONにした場合は親から復元できるわけだからparentというプロパティは不要だとする。

そこでクラスAを次のように修正する。

class A
  def initialize(caption, data, parent)
    @caption = caption
    @data = data
    @parent = parent
  end
  attr_reader :caption, :data
  def as_json(opts = {})
    super(opts.merge(except: :parent))
  end
end

が、不思議なことにこの場合もstack level too deepとなる。

そこで、as_jsonではなく、to_jsonで直接欲しいJSONを作ることにしてみる。

class A
  def initialize(caption, data, parent)
    @caption = caption
    @data = data
    @parent = parent
  end
  attr_reader :caption, :data
  def to_json(opts = {})
     {caption: caption, data: data}.to_json
  end
end

が、これもstack level too deepとなる。

まさか、to_jsonの呼び出しがまずいのかな? と以下のように変えてみる。

class A
  def initialize(caption, data, parent)
    @caption = caption
    @data = data
    @parent = parent
  end
  attr_reader :caption, :data
  def to_json(opts = {})
    "{\"caption\": \"#{caption}\", \"data\": \"#{data}\"}"
  end
end

やはりstack level too deepとなる。

実はA#to_jsonは呼ばれていないので、to_jsonを変えることには意味はない。

つまり、as_jsonをオーバーライドしなければならないのだが、ここでsuperを呼び出すのではなく、to_jsonを呼び出し可能なオブジェクトに変えると期待している動作となる。

class A
  def initialize(caption, data, parent)
    @caption = caption
    @data = data
    @parent = parent
  end
  attr_reader :caption, :data
  def as_json(opts = {})
    {caption: caption, data: data}
  end
end
(...)
puts list.to_json #=> {"items":[{"caption":"a","data":0},{"caption":"b","data":1}]}

したがって、as_jsonをオーバーライドすれば良いということは間違いない。で、いろいろ試した結果、シンボルではなく文字列を使ってプロパティを指定するということにやっとたどりついた。

def as_json(opts = {})
  super(opts.merge(except: 'parent'))  # => 期待通りに振る舞う
end

が、プロパティ数が上の例のように十分に少なければas_jsonに直接Hashを書いたほうが余計な動作が不要なので良いと思う。

というのは、この例の呼び出しは、ActiveSupport(7.0.2.3の場合)のcore_ext/object/json.rbの59行目からのas_jsonが最初に呼ばれて、次にcore_ext/object/instance_variables.rbの14行目からのinstance_valuesが呼び出され、この時点でプロパティ名の文字列をキーとしたHashが生成され、最終的にcore_ext/hash/except.rbの12行目のexceptでas_jsonのオプションに与えたexceptが処理されるからだ(このため、プロパティ名にシンボルを与えるとHashからの削除処理が無視される。けど、except.rbのドキュメントではキーとしてシンボルを前提としているから、シンボルにしたほうが良さそうな気もするがおそらく互換性問題が出てくるのかなぁ)。

要は捨てるプロパティについても値の取得を行っているから無駄だ。

いかがでしたか、as_jsonのオプションに与えるexceptで指定する除外プロパティには文字列を使うか、またはas_jsonで必要なプロパティを抽出したHashを返す、これで循環参照を回避できる。


2022-06-19

_ ガイズ&ドールズ

子供の父の日プレゼントで帝国劇場にガイズ&ドールズを観に行く。

舞台はニューヨークはブロードウェイ、1930年代。通りにはばくち打ちがたむろしていて、時折救世軍の行進が通る。

まず舞台のギミックがおもしろい。

主なシーンとなる街角(救世軍の伝道所がある地下へ通じる入口があるビルと、地下鉄の入り口がある)、救世軍の伝道所(というわけで、前のシーンとこのシーンで舞台が上下する)、飛行場のタラップ、飛行機、ハバナのクラブだが、行きのタラップと飛行機のつながりがおもしろいと思ったら、帰りはもっとおもしろかった。タラップが下がると街角の地下鉄の入り口になる。さらに、やたらと広い下水道。幕を閉めるとその手前が14年間も婚約状態のまま放置されている歌手(男が真人間になったら結婚するという約束をしているのだが、まったくばくちから足を洗わないので結婚できないし、男側も自分がまともに家庭を持つことに尻込みしているのでどうにもならない)のショーの舞台となる。

最初、透過スクリーンに大東宝の映画(シネスコサイズ)の始まりが映される。うまくできているので、透過スクリーンの向こうが本物の舞台となっているとは思わず、よくこんなこった映画を舞台のために撮影したなと驚いた。最後も同様に映画の終映が映される。

この開幕の音楽というか序曲が実に良い。音楽では1幕最後の一番の主人公の女たらしのばくち打ちのスカイと救世軍の軍曹のサラのデュエットが美しい。サラが酔っ払って暴れまくるところの元気いっぱい感が実にうまい。マドモアゼルモーツァルトの人だった。

でも、なんか自分でもよくわからないが、最後スカイに頼まれてたくさんのばくち打ちがしぶしぶながらも楽しそうに救世軍の集会に行くところが実に好きだ。

この作品の登場人物のようなろくでもないが愛すべきでもあるばくち打ちがたくさん出てくる作品を以前読んだなと思い出した。

ブロードウェイの天使 (新潮文庫)(デイモン・ラニアン)

(表題作は病気の捨て子の面倒をしぶしぶながら見る羽目になったばくち打ちが仲間のばくち打ちに助けられながら(もちろんブーブー文句を言われまくりながら)育てる物語で、このあたりの本当はいやでいやでしょうがないというそぶりを見せながらも実は真人間的な真情があってくそまじめに助け合ってしまうところのニュアンスがすごく似ている。だから表題の「天使」はもちろん薄幸の孤児のことなのだが「天使たち」にも通じる)

というか、そもそもラニアンがガイズ&ドールズの原作者だったのかと今Wikipediaを読んで知った。


2022-06-24

_ 駅馬車

BSで駅馬車をやっていたので録画して観た。そういえば数週間前のリオ・ロボもみたので、ジョンフォードとハワードホークスにジョンウェインを配した西部劇の代表作を観たことになる。多分、本当に子供の頃にテレビで観たような記憶がないわけでもないが、まともに観たのはこれが最初だ。

駅馬車が町にやってくる。到着した身重(しかも臨月らしいのだが、そういう厄介な特徴は台詞だけに留まっていてちょっとおもしろい)の婦人は騎兵隊の大尉である夫の駐在地に来たわけなのだが、残念、彼は隣町へ移動した後だった。かくして駅馬車の旅を続けることにする。

一方、町では婦人会が反道徳的な人たちの追放を始めている。

かくして娼婦が町からの追放を突き付けられる。同様に始終酔っ払っている医者も追放される。かくして二人は駅馬車に乗らざるを得なくなる。そういう町だから酒の行商人(なぜか牧師のような服を着ているのでいつも間違えられる)もこの町での商売に見切りをつけて(かどうかはわからん)やはり駅馬車の人となる。というか医者に試供品を飲まれまくる。

その婦人会の親玉の夫は銀行をやっているのだが、今まさに預けられた5万ドルに目が眩み(だけではなく、この町に見切りをつけたのかも知れないし、奥さんが狂信的で気持ち悪くて我慢の限界となったのかも知れないし、ちょうど町の電信が故障したのを奇貨としたのかもしれない)やはり駅馬車に乗り込む(ただし町外れで)。電信が故障したというのはある種の伏線となっていて、やたらと頭取が駅馬車の出発を急がせる理由となっている(が、残念、目的地に着くと電信は直っているのだった)

さらには妙に紳士的に振る舞う賭博師は身重の婦人の護衛を自らかって出て駅馬車に乗り込む。ジョンキャラダインなのだが狐過ぎる。なんとなく七人の侍の久蔵を想起して、こいつは死ぬと思ったら本当に死んでしまった。

南北戦争をどう呼ぶかで、医者と賭博師の間で言い合いがある(というか、医者が反乱というような言い方をすると、賭博師が解放戦争だと言い直すように迫る)。

その頃保安官事務所にはリンゴ・キッドが脱獄したという情報が入ってくる。ということはやつは駅馬車に乗り込むに違いないと保安官も駅馬車に乗る。

アパッチ族が進軍したという情報があるため、騎兵隊が護衛につく。その情報をもたらすのはシャイアン族なのだが、「ていうか野郎もアパッチじゃんか」「ばか、ありゃおれたちの味方のシャイアンだ」というようなやり取りで説明される。

町を出ると案の定リンゴ・キッドが乗り込んでくる。保安官はリンゴのライフルを取り上げる。

という最初の町を出発するまでにすべての物語の前提を凄まじい勢いでまくし立てる。うまい。

そして行く先々ですべて回収していく。

夫を訪ねてきた身重の婦人に対しては、夫が戦争で傷ついたというショックと、ショックによって産気づいて、医者が取り上げて娼婦が赤ん坊の面倒を一生懸命みる。

たった17歳で収監されていた(おそらく女性を知らない)リンゴ・キッドはその姿を見て結婚をもちかける。

渡し舟はアパッチに破壊されているため、馬車に浮きをくくりつけ、馬に渡河させる。本当にこういうことあったのかなぁ?(馬車は木箱だからできなくはないだろうけど)

アパッチが襲撃してくる。馬車に追いついた一人が馬にまたがり馬車から外そうとする。が、保安官かキッドに撃たれる。それでもしがつみくのだが、さらに撃たれて転がり落ちる。その上を後続の馬が駆け抜け、おまけに馬車も通り過ぎる。すげぇアクションだ。

南軍の矜持と貴族的な振る舞いにやたらと気をつけている賭博師は南部の大物の子弟だということを最後にぽつりと呟きながらフラグ通りにアパッチの襲撃で受けた銃弾で息を引き取る。

頭取は逮捕される。

婦人は蔑んでいた娼婦に対して心からの謝意を述べる。

保安官はキッドの復讐を見て見ぬふりをする。そしてキッドは父親と弟の仇を討つ(早打ち合戦はまったく描写されずにライフルの音が1発、拳銃の音が1発、さらにライフルの音が2発聞こえる)。

医者と保安官はキッド夫婦を送り出す。

なるほど、これは誰が観ても傑作としか言いようがない作品だった。

駅馬車(字幕版)(ジョン・ウェイ)


2022-06-28

_ ガランチャのリサイタル

すみだトリフォニーホールでガランチャ。このホールは初めてだが、実に調度が美しい。始まると音も良くて(弱い音が弱く、強い音は強く聞こえるし、残響も適度だ)気に入った。しかも椅子が疲れない。

2部構成で1部はドイツ・フランスの欧州ど真ん中で、2部がロシアとスペインという西南と東北の欧州辺境。

ドイツはブラームスで1曲目は拍子抜けするほどさらさらとした曲で喉を温めるのにちょうど良いのかなぁとか考えながら聴く。で、2曲目、3曲目と進み、やはりブラームスはそれほど好みではないなぁとか考えていたら4曲目が美しい。というかガランチャは素晴らしい。震わせる声ではなく細かな音がたくさん乗っているからだ。さらに5曲目は曲そのもの含めて抜群。でも6曲目は最後盛り上がるがやはりそれほど好みではないと考えているうちに、サビが独特な作曲家でベルリオーズ登場。名曲だ。

で、月の光が伴奏者のソロで、比較的速めのテンポだが美しい。というかドビュッシーは好きだ。

で、サムソンとデリラのあなたの声がになる。特に最後のサムソン、サムソンのあたりはぞくぞくするほど美しい。

最後のサバの女王はたぶん初めて聴くがこれも良い。

休憩をはさんでチャイコフスキーのオルレアンの乙女で、これは初耳。全然チャイコフスキー的ではない不思議な曲。

ラフマニノフから3曲、1曲目はまあラフマニノフかなぁくらいなのだが、2曲目がいかにもラフマニノフな半音を使った上昇形が2回続くやつですごく好きだ。3曲目も悪くない。

伴奏者のソロでグラナドスがあって、名前忘れたタイプの曲が3曲。最後の曲はCDで聴いたことがあるが、すごいテンポで盛り上げた。

アンコールはハバネラから始まる。最後、伸ばしに伸ばしてすごい。続いてオミオバンビーノカロで悪くない。3曲目は良くわからなかったが(フェイバリットらしい)ラフマニノフ。続いてマスカーニのサントゥッツァのアリア。ソプラノの曲じゃないか? と思ったらメゾでも歌えるらしいというか歌っていた(そういえばオミオバンビーノカロもソプラノの曲だった)。しかも考えたら持っているCDの中にも入っている。本来はそこで終わりらしかったが、その後、軽い曲を1つ、続いてやはり軽めの曲で本当におしまい。

伴奏者よりも微妙にガランチャのほうが背が高いがいずれにしてもそれなりに長身の二人に対してピアノの譜面めくりの人がやたらと小柄(少なくともガランチャに比べれば小柄)で、彼女が出てくるとアンコールで歌うということで拍手が大きくなるのがちょっとおもしろかった。

それにしてもブラームスのような大して好きでもない作曲家の聴いたことのない曲でも見事に聴かせてくれるのだからとんでもなくすごい歌手だとあらためて思った。本当に良いものを聴けた。

Revive(エリーナ・ガランチャ & バレンシア自治州管弦楽団 & ロベルト・アバド)


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|

ジェズイットを見習え