投稿者: koji

  • 「自己」の7つの面(ラマチャンドラン)

    まえがき

    『以上の七つの面は、テーブルの脚のように一緒にはたらいて、私たちが自己と呼んでいるものを支えている。』

    リスト

    あとがき

    まえがきを含めて、V・S・ラマチャンドラン『脳のなかの天使』 (角川書店、2013年)より。リストは本文の要約・引用です。

    学術的な定義ではなく、挙げてみた、という体でリストアップされていました。うまく括りなおせば「自我意識の4条件(ヤスパース)」に集約できそうに思います。

    本書は、人が当たり前のように持っているこれらの側面が『錯覚や妄想や障害におかされやすい』ことを豊富な症例とともに説明してくれます。

    • タイトル脳のなかの天使
    • 著者: V・S・ラマチャンドラン(著)、山下 篤子(翻訳)
    • 出版社: 角川書店(角川グループパブリッシング)
    • 出版日: 2013-03-23
    • ショートコード内で出力するHTMLをブロックエディタでデザインするために再利用ブロックを活用する

      投稿の中にHTMLをダイナミックに挿入するショートコードをいくつか作っています。たとえば [ lf_bookinfo asin=XXX] というショートコードは ASIN(Amazon.co.jp における書籍ID)をパラメータとし、書影や書籍情報、関連するリストなどを出力します。

      これまではショートコードに登録したコールバックの中で素朴にHTMLを書いていました。しかしブロックエディタには「縦積み」「横並び」のようなデザインブロックがあって、複雑なレイアウトを簡単に作れます。

      この恩恵に与りたいと思い、ブロックエディタが生成したコードをショートコードのコールバック内にコピーしたりしてみました。が、ブロックエディタが生成する複雑なクラスなどに追随するのが大変で断念。新しく専用ブロックを作成して既存の投稿を全置換するのが正道。しかしブロックの作成もまた面倒でした。

      試行錯誤の末、表示したいHTMLを再利用ブロックとして登録し、ショートコードの中から呼び出す方法に落ち着きました。

      表示レイアウトをデザインして再利用ブロックとして保存

      表示させたい情報をブロックエディタでレイアウトし、ダミーのテキストや画像を挿入しておきます。

      下部の見出しとリストはデータがあれば表示し、なかったら表示しないのですが、とりあえず表示させる前提でデザインしておきます。これを再利用ブロックとして保存すると、 <!-- wp:block {"ref":NNN} /--> のようなコードが挿入されます。

      ショートコード内から再利用ブロックを呼び出す

      WordPress はブロックを解析(パース)して表示用のHTMLを描画(レンダー)し、その後でショートコードをコールバックの出力で置き換えます。ショートコードが処理される時点では、本体のブロックパース&レンダリングは終わってしまっています。よって再利用ブロックのパースとレンダリングは手動で行わねばなりません。

      再利用ブロックは 投稿タイプ wp_block の投稿なので、それを呼び出してブロックにパースします。パースも標準関数があるので簡単です。

      // 再利用ブロックを取得
      $q = new WP_Query( [
          'post_type' => 'wp_block',
          'p'         => NNN,
      ] );
      
      // HTMLをブロックにパースする
      $parsed_blocks = parse_blocks( $q->posts[0]->post_content );

      ブロックの内容を置き換える

      内容を置き換えるブロックには、再利用ブロックを作るときに固有のCSSクラス名を振っておきます。意味合い的にはIDがふさわしいところですが、IDはブロックの属性情報としては保持されていない(出力HTMLにのみ書き込まれている)ので扱いづらい。

      次のようなイメージで、ブロックの内容を置き換えていきます。

      // 特定のクラスのブロックの内容を置き換える
      block_replace( $parsed_blocks[0], [
          'class' => 'lf-attribute-as-id',
          'from'  => '<li>(attribute)</li>',
          'to'    => '<li>1行目</li><li>2行目</li>',
      ] );

      ブロックの内容を置き換える処理はこんな感じ。ブロックおよびブロック内ブロックを再帰的に探索し、クラス名が一致したブロックの innerContentを置き換えます。パースして得られたブロックを直接置き換えていくために参照渡しにしています。

      function block_replace( &$block, $args ) {
      
          // 渡されたブロックを直接書き換えるのでリファレンス渡し
          foreach ( $block as &$b ) {
      
              // 枝葉
              if( ! is_array( $b ) ) {
                  continue;
              }
      
              // 置換対象のブロックなら
              $cn = $b['attrs']['className'] ?? '';
              if ( $args['class'] === $cn ) {
      
                  // このブロックの innerContent を置き換える
                  $b['innerContent'][0] = str_replace(
                      $args['from'],
                      $args['to'],
                      $b['innerContent'][0]
                  );
      
                  break;
              }
      
              // 直下に innerBlocks か添字配列があれば再帰呼び出し
              if ( array_key_exists( 'innerBlocks', $b )
                  || array_key_exists( 0, $b ) ) {
      
                  block_replace( $b, $args );
              }
          }
      }

      再帰ってすばらしい。

      array_walk_recursive() でも

      置き換える元となる文字列(この例では ‘<li>(attribute)</li>’)を一意にしておけば、array_walk_recursive() で置換する方法もあります。クラス指定も要らないし楽かも。

      array_walk_recursive( $parsed_blocks, 'block_replace', [
          'from'  => [
              '<li>(attribute)</li>',
              '(more-heading)',
          ],
          'to'    => [
              '<li>1行目</li><li>2行目</li>',
              $more_heading_to,
          ],
      ] );
      
      function block_replace( &$item, $key, $args ) {
      
          $item_replaced = str_replace( $args['from'], $args['to'], $item, $count );
          if ( 0 !== $count ) {
              $item = ( '' !== $args['to'] ) ? $item_replaced : '';
          }
      }

      array_walk_recursive() のコールバック関数の中で、置換先の文字列が空のときにブロック要素を丸ごと消している($item に ’’ を代入している)のは、<h>や<ul>などの外側のHTMLを含めてすべて削除するためです。

      HTML出力

      そのような処理を置き換えたいブロックについて実施した後、HTMLにレンダーしてコールバック終了。

      return render_block( $parsed_blocks[0] );

      少々面倒ではありましたが、既存の投稿を変更しなくてよい点、ブロックエディタでデザインできる点、そして再利用ブロックなので変更を一斉に及ぼせる点はメリットです。

    • 投書がボツになる理由(杉村 楚人冠)

      まえがき

      『記者にして随筆家・俳人でもあった杉村楚人冠(略)が、新聞に寄せられる読者の投書を論評しています。ダメな投書の実例を晒してダメ出しまでするという、かなりの上から目線記事なんです。(略)そして、投書がボツになる理由を三つあげてます。』

      リスト

      あとがき

      まえがきを含めて、パオロ・マッツァリーノ『思考の憑きもの 論より実践のクリティカルシンキング』 (二見書房、2021年)より。リストは本文からの引用です。

      引用元は、朝日新聞に1909(明治42)年6月20日から6日間掲載された「投書と投書家」という短期連載とのこと。投書家という言葉を初めて見た気がします。投書家を名乗る人がいたくらい新聞投書に人気があったのか、この連載のための造語なのか。文献情報と杉村 楚人冠の名前をメモしておきたく収集しました。

      前二者は文章の内容を理由としていますが、3つめは投書者の属性を理由にしています。なぜ匿名の投書はボツなのか。引用元にあたれなかったのでマッツァリーノ氏の要約を引用します。

      新聞社側から例をいいたいくらいに立派な内容の投書でも、何を恐れてか名を書かない。いわんや人の悪口陰口などに到っては名のないのが当然である、と楚人冠の怒りはおさまりません。

      朝日新聞や読売新聞のような全国紙が創刊されたのは明治時代のはじめ。匿名投書はマス媒体の登場当初から読み手の心をざわつかせていたことがうかがえます。

      • WordPress: ショートコードのブロック化

        例えば下記のページは、固定ページにショートコードを埋め込んでコンテンツを動的に生成している。

        その編集画面は下図(Before)。ショートコードの中で見出しやリストなどすべてのコンテンツの書き出しを行っているのでブロックエディタの恩恵を被れない。

        カスタムブロックを作ってみたが、開発環境が複雑で維持できる自信がない。そこでカスタムブロックを作ることなく、ブロックエディタでレイアウトする自由を享受する方法を考えた。

        具体的には、下図(After)のようにページのデザインをブロックエディタで行い、表示時にブロックの内容の一部を置き換えることにした。

        Before
        After

        これをするためには、下記の処理が必要。

        • 置換したいブロックに一意なクラス名を指定する
        • render_block フィルターフックでそのクラス名を拾ってブロックの内容を置き換える

        ブロックを一意に特定するならば意味合い的にはID(HTMLアンカー)が適切だが、IDはブロックの属性として定義されていないため、キーとして使いづらい。

        コードは次のような感じで準備して、プラグインファイルから LF_Page_Taginfo::init() を呼んでおく。

        class LF_Page_Taginfo {
        
            // ブロックのクラス名 => 置換情報テーブル
            private static array $blocks = [];
        
            /**
             * 初期化
             */
            public static function init() {
                add_action( 'wp', [ __CLASS__, 'wp' ] );
            }
        
            /**
             * ディスパッチャー
             */
            public static function wp() {
        
                // 対象ページでなければリターン
                if ( ! is_page() || 'taginfo' !== get_query_var( 'pagename' ) ) {
                    return;
                }
        
                // パラメーターが無ければリターン
                if ( '' === $tag_slug = get_query_var( 'tag' ) ) {
                    return;
                }
        
                // タームオブジェクトが作れなければリダイレクト
                if ( false === $term = get_term_by( 'slug', $tag_slug , 'post_tag' ) ) {
                    wp_safe_redirect( home_url(), 302 );
                    exit;
                }
        
                // ブロックのクラス名 => 置換情報テーブル
                // クラス名はブロックエディタで一意に指定しておく
                self::$blocks = [
                    'lf-page-taginfo-header-cotagged' => [
                        'from' => '(タグ)',
                        'to'   => $term->name,
                    ],
                    'lf-page-taginfo-header-tagcloud' => [
                        'from' => '(共起タグ)',
                        'to'   => LF_Page_Tag_CoTagged::get_for_taginfo_page( $term, 5 ),
                    ],
                    'lf-page-taginfo-header-list' => [
                        'from' => '(タグ)',
                        'to'   => $term->name,
                    ],
                    'lf-page-taginfo-list' => [
                        'from' => '<li>(リスト)</li>',
                        'to'   => LF_Tax_Tag::get_for_taginfo_page( $term, 5 ),
                    ],
                    'lf-page-taginfo-header-book' => [
                        'from' => '(タグ)',
                        'to'   => $term->name,
                    ],
                    'lf-page-taginfo-book' => [
                        'from' => '<li>(書籍)</li>',
                        'to'   => LF_Page_Tag_Book::get_for_taginfo_page( $term, 5 ),
                    ],
                    'lf-page-taginfo-misc' => [
                        'from' => [ 'TAG', '(タグ)' ],
                        'to'   => [ urlencode( $term->name ), $term->name ],
                    ],
                ];
        
                // ページタイトル <title> の変更(コールバック関数は省略)
                add_filter( 'document_title_parts', [ __CLASS__, 'document_title' ], 10, 1 );
        
                // ページ説明の追加(コールバック関数は省略)
                add_action( 'wp_head', [ __CLASS__, 'wp_head' ] );
        
                // 投稿タイトルの変更(コールバック関数は省略)
                add_filter( 'the_title', [ __CLASS__, 'the_title' ], 10, 2 );
        
                // 投稿抜粋欄に説明を表示する(コールバック関数は省略)
                add_filter( 'get_the_excerpt', [ __CLASS__, 'excerpt' ], 10, 2 );
        
                // ブロックを置換する
                add_filter( 'render_block', [ __CLASS__, 'render_block' ], 10, 3 );
            }
        
            /**
             * ブロックを置換する
             */
            public static function render_block( $block_content, $parsed_block, $instance ) {
        
                $class = $parsed_block['attrs']['className'] ?? '';
        
                // 置換対象のクラスなら置換
                if ( '' !== $class && array_key_exists( $class, self::$blocks ) ) {
                    $block_content = str_replace(
                        self::$blocks[$class]['from'],
                        self::$blocks[$class]['to'],
                        $block_content
                    );
                }
        
                return $block_content;
            }
        }
        
        • 表示しようとしているページが処理対象かどうかを知るには ‘init’ アクションフックではタイミングが早すぎるので、URLパラメータの処理が終わった ‘wp’ で行っている。
        • wp() の最初の3つの if 文が対象ページかどうかの判定とパラメータ検証。
        • self::$blocks の定義が肝。ブロック名をキー、置換元先情報を値とする連想配列を定義しておく。置換されない部分についてはできるだけブロックエディタのほうに記述する。置換する部分がエディタ上でわかりやすいようにカッコでくくってみた。
        • 置換は str_replace() で行うので 複数要素の置換も可能。いちばん最後の要素ではリンク先のURLとリンク文字列の置換を行っている。
        • ‘render_block’ フィルターフックのコールバックに置換処理を登録。このフックはブロック描画の最後に設置されており、ヘッダーやフッターも含めて全ブロックで発火する。よってブロック名ごとに発火できる ‘render_block_{$this->name}’ を使うほうが少し軽いのかも。
        • render_block() で置換。クラス名が存在し、かつ置換情報テーブルのキーと一致したら置換。ブロックエディタでクラス名が1つだけ登録されていることを前提としているので、もしカスタムクラス名を2つ登録したくなった場合には改変が必要。
        • $block_content には表示するHTMLがそのまま入っている。置換元のコードはコードエディターに切り替えるなどして確認する。

        ちょっとスペーサーを入れてみたりするような見栄えの調整がずいぶん楽になった。

      • ビッグデータの特性 (4V)

        まえがき

        『データの収集、取捨選択、管理及び処理に関して、一般的なソフトウェアの能力を超えたサイズのデータ集合と定義される(1)』ビッグデータの特性とは。

        リスト

        あとがき

        まえがきは「ビッグデータ」(Wikipedia日本語版)より。リスト項目は “Big data” (Wikipedia) を読みつつ私訳しました。

        オリジンはVeracityを除いた3V。こういった技術的な用語を Wikipedia で探すときにはまず英語版から始めるのですが、今回は英語版に無い情報が日本語版にだけ書かれていて少々びっくりしました。ありがたく引用します。

        2001年の研究報告書(2)で、METAグループ(現ガートナー )のアナリスト、ダグ・レイニーはビッグデータの特性としてボリューム(volume、データ量)、速度(velocity、入出力データの速度)、バラエティ(variety、データ種とデータ源の範囲)があると定義した。

        この三つ組はたしかにビッグデータとそうでないデータを分かつ特性と思えます。一方で正確さ(Veracityなんて単語があるんですね)はビッグデータであろうがなかろうがデータ処理においては重要な特性で、付け足し感が否めません。にもかかわらず4つめのVとしてフィーチャーされたのは、3Vがいずれも正確さを下げる要因となるからでしょう。リスト項目ではそのニュアンスをカッコ内に添えました。

        こういうリストは優れたフレームワーカーが最初に発案し、流布するにしたがい付け足され、そのたびに質が下がっていくように思います。5つめのVとしてValue(価値)があるとしている文章も見かけましたが、わざわざ Value を足す Value はないような。

        参考文献

        (1) “‘Big Data’: Big gaps of knowledge in the field of Internet.

        (2) Douglas, Laney. “3D Data Management: Controlling Data Volume, Velocity and Variety”. Gartner.

      • 国の開発の程度を計測する基準(人間開発指数)

        まえがき

        『アマルティア・セン(略)は、パキスタン人経済学者のマブーブル・ハックと共同で、1990年に「人間開発指数」と呼ばれるものを開発した。現在この指数は、国の開発の程度を計測する基準として広く用いられている。』

        リスト

        あとがき

        まえがきは、サンヌ・ブラウ『The Number Bias 数字を見たときにぜひ考えてほしいこと』 (サンマーク出版、2021年)からの引用です。リストは「人間開発指数」(Wikipedia) および「よくあるご質問:人間開発指数(HDI)とは」(国連開発計画(UNDP))からの要約・引用です。『The Number Bias』では『「平均寿命」「教育を受ける年数」「収入」』となっていました。

        開発が進んだ国とは、国民がよく学び、よく稼ぎ、長生きしている国。なるほど。

        幸福度ランキングというものが時々話題になりますが、幸福度のような主観が最終的なアウトプット(結果として人が到達する状態)だとすると、その一段階手前を計測しているイメージですかね。

        この3つの指標に絞り込むまでのプロセスなどを追ってみたい。

        この本からの他のリスト

      • 数字に入り込む「5つの主観」

        まえがき

        『知能のような抽象的な概念を標準化するには、その過程でいろいろな選択が必要になる。数字は一見すると客観性のオーラをまとっているが、その裏にはえてして「主観的な決断」が隠れているものだ。』

        リスト

        あとがき

        まえがきを含めて、サンヌ・ブラウ『The Number Bias 数字を見たときにぜひ考えてほしいこと』 (サンマーク出版、2021年)より。リストの見出し部分は本文からの引用です。本文の内容の意訳を解説に添えました。

        5のところに印象的なエピソードがありました。第一次世界大戦中に実施された知能テストの結果、移民や黒人は点数が低く、また点数と教育を受けた年数の間に強い(正の)相関があったそうです。

        しかし実施者は、教育によって知能を高め得るとは考えず、教育を受ける年数が長いのは持って生まれた知能の高さによるものだと解釈し、人種差別的な提言を引き出す材料にしたとのこと。

        この本からの他のリスト

        参考文献

      • カリスマ性に結びつく性格特性

        まえがき

        『ある人物についてカリスマ性の評価を行うと、複数の人の評価が一致する傾向がある。その事実が、カリスマ性は受け手の感じ方だけで決まるのではなく、当人にカリスマ性につながるパーソナリティの基盤があることを示している。』

        リスト

        あとがき

        まえがきを含めて、ジャスミン・ベルガウヴェ他「カリスマ性が強すぎると評価が下がり、成果も上がらない」より。ハーバード・ビジネス・レビュー編集部(編集) 『人の上に立つということ』 (ダイヤモンド社、2021年)所収。

        まえがきの参考文献として(1)が挙げられていました。リストは本文を編集・引用して作っています。「→」以降はそれぞれの性格特性の表れ。

        枠組みとしてピンとこなかったので、この4特性を規定している『仕事に関連した性格特性評価のツールであるホーガン・ディベロップメント・サーベイ (HBS)』 (Hogan Development Survey) を調べてみました。これは対人関係の問題の起こしやすさを測るサーベイのようです。

        つまりカリスマ性の定義というよりは、対人関係の問題につながる11の性格特性のうちカリスマ性に高い関連性を持つとして抽出された4つの項目ということ。

        • タイトル人の上に立つということ
        • 著者: ハーバード・ビジネス・レビュー編集部(編集)、DIAMONDハーバード・ビジネス・レビュー編集部(翻訳)
        • 出版社: ダイヤモンド社
        • 出版日: 2021-12-01

          参考文献

          (1) Sosik, John J. “Self-other agreement on charismatic leadership: Relationships with work attitudes and managerial performance.” Group & Organization Management 26.4 (2001): 484-511.

        • 認知的機能の学習モデル (ACT*)

          まえがき

          『Andersonは認知的技能の学習においてACT*モデルを提唱した。これは3段階からなる。Fittsの運動技能学習の3相説と対比すると、両者の類似性が明らかになる。』

          リスト

          あとがき

          まえがきを含めて、参考文献(1)より。まえがきの「Fittsの運動技能学習の3相説」は「運動学習の3段階」のこと。

          「運動学習の3段階」の引用元は1964年の出版物でした。ACT*の基礎をなす理論(ACT-R – Wikipedia)と比較すると、運動学習のモデル化が先にあったようです。

          参考文献

          (1) 中村隆一. “トレーニングと運動学習 運動学習について.” 理学療法のための運動生理 9.3 (1994): 149-156.

        • 運動学習の3段階

          まえがき

          『スポーツで新たなスキルを習得する際、学習者は以下の3つの段階を経て熟達していく。』

          リスト

          あとがき

          まえがきを含めて、黒木 俊秀(監修)、小野 良平(翻訳)『ひと目でわかる 心のしくみとはたらき図鑑』 (創元社、2019年)より。

          運動技術を習得する3つの段階」と同じ内容です。こちらのほうがやや丁寧な解説でしたので別リストとして収集。

          原典は明示されていませんでした。検索してみると参考文献(1) のようです。

          「相」はフェーズですね。なお、『各相と各段階との関係は、研究者により異なる。』という訳注がありました。

          この本からの他のリスト

          参考文献

          (1) Fitts, Paul M. “Perceptual-motor skill learning.” Categories of human learning. Academic Press, 1964. 243-285.