2026年3月30日月曜日

ytp-widget

 <div id="ytp-widget-a1b2c3" class="ytp-widget-a1b2c3">

  <style>

    #ytp-widget-a1b2c3 {

      --ytp-bg: #0f1115;

      --ytp-panel: #171a21;

      --ytp-text: #f3f5f7;

      --ytp-sub: #aab4c0;

      --ytp-border: #2a3140;

      --ytp-btn: #202734;

      --ytp-btn-hover: #2a3344;

      --ytp-radius: 14px;

      --ytp-gap: 10px;

      --ytp-font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;


      font-family: var(--ytp-font);

      color: var(--ytp-text);

      background: var(--ytp-bg);

      border: 1px solid var(--ytp-border);

      border-radius: var(--ytp-radius);

      padding: 14px;

      box-sizing: border-box;

      width: 100%;

      max-width: 960px;

    }


    #ytp-widget-a1b2c3 *,

    #ytp-widget-a1b2c3 *::before,

    #ytp-widget-a1b2c3 *::after {

      box-sizing: border-box;

    }


    #ytp-widget-a1b2c3 .ytp-head {

      display: flex;

      justify-content: space-between;

      align-items: center;

      gap: 12px;

      margin-bottom: 10px;

      flex-wrap: wrap;

    }


    #ytp-widget-a1b2c3 .ytp-title {

      font-size: 15px;

      font-weight: 700;

      letter-spacing: 0.02em;

      margin: 0;

    }


    #ytp-widget-a1b2c3 .ytp-badge {

      font-size: 12px;

      color: var(--ytp-sub);

      border: 1px solid var(--ytp-border);

      border-radius: 999px;

      padding: 4px 10px;

      background: rgba(255,255,255,0.02);

    }


    #ytp-widget-a1b2c3 .ytp-player-wrap {

      position: relative;

      width: 100%;

      aspect-ratio: 16 / 9;

      background: #000;

      border-radius: 12px;

      overflow: hidden;

    }


    #ytp-widget-a1b2c3 .ytp-player {

      width: 100%;

      height: 100%;

    }


    #ytp-widget-a1b2c3 .ytp-controls {

      display: flex;

      flex-wrap: wrap;

      gap: 8px;

      margin-top: 12px;

    }


    #ytp-widget-a1b2c3 .ytp-btn {

      appearance: none;

      border: 1px solid var(--ytp-border);

      background: var(--ytp-btn);

      color: var(--ytp-text);

      padding: 10px 14px;

      border-radius: 10px;

      cursor: pointer;

      font: inherit;

      line-height: 1;

      transition: background 0.2s ease, transform 0.08s ease;

    }


    #ytp-widget-a1b2c3 .ytp-btn:hover {

      background: var(--ytp-btn-hover);

    }


    #ytp-widget-a1b2c3 .ytp-btn:active {

      transform: translateY(1px);

    }


    #ytp-widget-a1b2c3 .ytp-meta {

      margin-top: 12px;

      display: grid;

      grid-template-columns: repeat(2, minmax(0, 1fr));

      gap: 8px;

    }


    #ytp-widget-a1b2c3 .ytp-card {

      background: var(--ytp-panel);

      border: 1px solid var(--ytp-border);

      border-radius: 10px;

      padding: 10px 12px;

      min-width: 0;

    }


    #ytp-widget-a1b2c3 .ytp-label {

      display: block;

      font-size: 11px;

      color: var(--ytp-sub);

      margin-bottom: 4px;

    }


    #ytp-widget-a1b2c3 .ytp-value {

      display: block;

      font-size: 14px;

      font-weight: 600;

      white-space: nowrap;

      overflow: hidden;

      text-overflow: ellipsis;

    }


    #ytp-widget-a1b2c3 .ytp-debug {

      margin-top: 10px;

      font-size: 11px;

      color: var(--ytp-sub);

      white-space: normal;

      word-break: break-word;

    }


    @media (max-width: 640px) {

      #ytp-widget-a1b2c3 .ytp-meta {

        grid-template-columns: 1fr;

      }


      #ytp-widget-a1b2c3 {

        padding: 12px;

      }

    }

  </style>


  <div class="ytp-head">

    <h2 class="ytp-title">Playlist Player</h2>

    <div class="ytp-badge">GA4 direct</div>

  </div>


  <div class="ytp-player-wrap">

    <div id="ytp-player-a1b2c3" class="ytp-player"></div>

  </div>


  <div class="ytp-controls">

    <button type="button" class="ytp-btn" data-act="play">再生</button>

    <button type="button" class="ytp-btn" data-act="pause">停止</button>

    <button type="button" class="ytp-btn" data-act="prev">前へ</button>

    <button type="button" class="ytp-btn" data-act="next">次へ</button>

  </div>


  <div class="ytp-meta">

    <div class="ytp-card">

      <span class="ytp-label">状態</span>

      <span class="ytp-value" data-role="state">未初期化</span>

    </div>

    <div class="ytp-card">

      <span class="ytp-label">動画ID</span>

      <span class="ytp-value" data-role="video-id">-</span>

    </div>

    <div class="ytp-card">

      <span class="ytp-label">Playlist index</span>

      <span class="ytp-value" data-role="playlist-index">-</span>

    </div>

    <div class="ytp-card">

      <span class="ytp-label">再生秒数</span>

      <span class="ytp-value" data-role="current-time">0</span>

    </div>

  </div>


  <div class="ytp-debug" data-role="debug"></div>


  <script>

    (function () {

      const ROOT_ID = 'ytp-widget-a1b2c3';

      const PLAYER_ID = 'ytp-player-a1b2c3';

      const root = document.getElementById(ROOT_ID);

      if (!root) return;


      const CONFIG = {

        gaMeasurementId: 'G-VYN4SZK0E6',      // 例: G-XXXXXXXXXX

        playlistId: 'PLKWIg8_Q-4Urj1UYEUudqpU7ySBROEVAK',      // 例: PLxxxxxxxxxxxxxxxx

        widgetName: 'yt_playlist_widget',

        progressIntervalSec: 10

      };


      const els = {

        state: root.querySelector('[data-role="state"]'),

        videoId: root.querySelector('[data-role="video-id"]'),

        playlistIndex: root.querySelector('[data-role="playlist-index"]'),

        currentTime: root.querySelector('[data-role="current-time"]'),

        debug: root.querySelector('[data-role="debug"]'),

        buttons: root.querySelectorAll('.ytp-btn')

      };


      let player = null;

      let progressTimer = null;

      let lastProgressBucket = -1;

      let lastVideoId = '';

      let lastState = null;


      function debug(msg, extra) {

        const payload = Object.assign({ msg: msg }, extra || {});

        els.debug.textContent = JSON.stringify(payload);

      }


      function ensureGA4(callback) {

        if (window.gtag && window.__ytpGaReadyA1B2C3) {

          callback();

          return;

        }


        if (!document.getElementById('ga4-script-a1b2c3')) {

          const s = document.createElement('script');

          s.id = 'ga4-script-a1b2c3';

          s.async = true;

          s.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(CONFIG.gaMeasurementId);

          document.head.appendChild(s);

        }


        window.dataLayer = window.dataLayer || [];

        window.gtag = window.gtag || function(){ window.dataLayer.push(arguments); };


        if (!window.__ytpGaReadyA1B2C3) {

          window.gtag('js', new Date());

          window.gtag('config', CONFIG.gaMeasurementId, {

            send_page_view: true

          });

          window.__ytpGaReadyA1B2C3 = true;

        }


        callback();

      }


      function track(eventName, params) {

        ensureGA4(function () {

          window.gtag('event', eventName, Object.assign({

            widget_name: CONFIG.widgetName,

            playlist_id: CONFIG.playlistId

          }, params || {}));

        });

      }


      function stateLabel(state) {

        if (!window.YT || !window.YT.PlayerState) return '不明';

        switch (state) {

          case YT.PlayerState.UNSTARTED: return '未開始';

          case YT.PlayerState.ENDED: return '終了';

          case YT.PlayerState.PLAYING: return '再生中';

          case YT.PlayerState.PAUSED: return '停止中';

          case YT.PlayerState.BUFFERING: return '読込中';

          case YT.PlayerState.CUED: return '準備完了';

          default: return '不明';

        }

      }


      function getVideoId() {

        try {

          return player && player.getVideoData ? (player.getVideoData().video_id || '') : '';

        } catch (e) {

          return '';

        }

      }


      function getPlaylistIndex() {

        try {

          const idx = player && player.getPlaylistIndex ? player.getPlaylistIndex() : null;

          return idx === null || idx === undefined ? '' : String(idx);

        } catch (e) {

          return '';

        }

      }


      function getCurrentTime() {

        try {

          return Math.floor(player && player.getCurrentTime ? player.getCurrentTime() : 0);

        } catch (e) {

          return 0;

        }

      }


      function updateUI() {

        els.videoId.textContent = getVideoId() || '-';

        els.playlistIndex.textContent = getPlaylistIndex() || '-';

        els.currentTime.textContent = String(getCurrentTime());

      }


      function stopProgressTracking() {

        if (progressTimer) {

          clearInterval(progressTimer);

          progressTimer = null;

        }

      }


      function startProgressTracking() {

        stopProgressTracking();

        progressTimer = setInterval(function () {

          if (!player || !window.YT) return;

          if (player.getPlayerState() !== YT.PlayerState.PLAYING) return;


          const sec = getCurrentTime();

          const bucket = Math.floor(sec / CONFIG.progressIntervalSec);

          updateUI();


          if (bucket !== lastProgressBucket) {

            lastProgressBucket = bucket;

            track('yt_playlist_progress', {

              video_id: getVideoId(),

              playlist_index: getPlaylistIndex(),

              progress_seconds: sec

            });

          }

        }, 1000);

      }


      function bindButtons() {

        els.buttons.forEach(function (btn) {

          btn.addEventListener('click', function () {

            if (!player) return;

            const act = btn.getAttribute('data-act');


            if (act === 'play') player.playVideo();

            if (act === 'pause') player.pauseVideo();

            if (act === 'prev') player.previousVideo();

            if (act === 'next') player.nextVideo();


            track('yt_playlist_control_click', {

              control_name: act,

              video_id: getVideoId(),

              playlist_index: getPlaylistIndex(),

              current_time_seconds: getCurrentTime()

            });

          });

        });

      }


      function onPlayerReady() {

        updateUI();

        bindButtons();


        track('yt_playlist_ready', {

          video_id: getVideoId(),

          playlist_index: getPlaylistIndex()

        });


        debug('player_ready', {

          playlistId: CONFIG.playlistId

        });

      }


      function onPlayerStateChange(event) {

        const state = event.data;

        const videoId = getVideoId();


        els.state.textContent = stateLabel(state);

        updateUI();


        if (videoId && videoId !== lastVideoId) {

          lastVideoId = videoId;

          lastProgressBucket = -1;


          track('yt_playlist_video_change', {

            video_id: videoId,

            playlist_index: getPlaylistIndex()

          });

        }


        if (state !== lastState) {

          track('yt_playlist_state_change', {

            video_id: videoId,

            playlist_index: getPlaylistIndex(),

            player_state_code: state,

            player_state_label: stateLabel(state),

            current_time_seconds: getCurrentTime()

          });

          lastState = state;

        }


        if (window.YT && state === YT.PlayerState.PLAYING) {

          startProgressTracking();

        } else {

          stopProgressTracking();

        }


        if (window.YT && state === YT.PlayerState.ENDED) {

          track('yt_playlist_video_complete', {

            video_id: videoId,

            playlist_index: getPlaylistIndex(),

            watched_seconds: getCurrentTime()

          });

        }

      }


      function onPlayerError(event) {

        track('yt_playlist_error', {

          video_id: getVideoId(),

          playlist_index: getPlaylistIndex(),

          error_code: event.data

        });


        debug('player_error', { code: event.data });

      }


      function createPlayer() {

        if (!window.YT || !window.YT.Player) return;


        player = new YT.Player(PLAYER_ID, {

          width: '100%',

          height: '100%',

          playerVars: {

            listType: 'playlist',

            list: CONFIG.playlistId,

            autoplay: 0,

            rel: 0,

            modestbranding: 1,

            playsinline: 1

          },

          events: {

            onReady: onPlayerReady,

            onStateChange: onPlayerStateChange,

            onError: onPlayerError

          }

        });

      }


      function loadYouTubeAPI() {

        if (window.YT && window.YT.Player) {

          createPlayer();

          return;

        }


        const previous = window.onYouTubeIframeAPIReady;


        window.onYouTubeIframeAPIReady = function () {

          if (typeof previous === 'function') previous();

          createPlayer();

        };


        if (!document.getElementById('yt-iframe-api-a1b2c3')) {

          const tag = document.createElement('script');

          tag.id = 'yt-iframe-api-a1b2c3';

          tag.src = 'https://www.youtube.com/iframe_api';

          document.head.appendChild(tag);

        }

      }


      ensureGA4(function () {

        track('yt_playlist_widget_view', {

          component_id: ROOT_ID

        });

      });


      loadYouTubeAPI();

    })();

  </script>

</div>


情報にとって

美とは何か

2026年3月29日日曜日

sample

 <style>

.media-grid-x{

  display:flex;

  flex-wrap:wrap;

  gap:16px;

  margin:24px 0;

  justify-content:flex-start;

  align-items:stretch;

}


.media-card-x{

  box-sizing:border-box;

  flex:0 0 calc(25% - 12px);

  max-width:280px;

  min-width:220px;

  border:1px solid #ddd;

  border-radius:20px;

  overflow:hidden;

  background:#f7f7f7;

  box-shadow:0 4px 18px rgba(0,0,0,0.08);

  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;

  color:#111;

  display:flex;

  flex-direction:column;

}


.media-card-x-image{

  padding:18px 18px 8px;

}


.media-card-x-image img{

  display:block;

  width:100%;

  height:auto;

}


.media-card-x-body{

  padding:0 18px 18px;

  display:flex;

  flex-direction:column;

  flex:1;

}


.media-card-x-title{

  font-size:18px;

  font-weight:700;

  line-height:1.4;

  margin:0 0 8px 0;

}


.media-card-x-text{

  font-size:14px;

  color:#222;

  margin:0 0 18px 0;

  line-height:1.7;

}


.media-card-x-actions{

  margin-top:auto;

  display:flex;

  gap:12px;

  flex-wrap:wrap;

}


.media-card-x-btn{

  display:inline-block;

  padding:12px 16px;

  text-decoration:none;

  border-radius:999px;

  font-size:14px;

  font-weight:700;

  white-space:nowrap;

}


.media-card-x-btn-primary{

  background:#111;

  color:#fff;

}


.media-card-x-btn-secondary{

  background:#aaa;

  color:#2d6cff;

}


@media (max-width:1100px){

  .media-card-x{

    flex:0 0 calc(50% - 8px);

    max-width:none;

  }

}


@media (max-width:680px){

  .media-card-x{

    flex:0 0 100%;

    max-width:none;

    min-width:0;

  }

}

</style>




<div class="media-grid-x">


  <div class="media-card-x">

    <div class="media-card-x-image">

      <img alt="批評テレビ" src="https://images-na.ssl-images-amazon.com/images/P/B0G1T5GVJD.09.MAIN._SCRMZZZZZZ_.jpg">

    </div>

    <div class="media-card-x-body">

      <div class="media-card-x-title">批評テレビ</div>

      <div class="media-card-x-text">君は酷の涙を見る</div>

      <div class="media-card-x-actions">

        <a class="media-card-x-btn media-card-x-btn-primary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD" target="_blank" rel="noopener noreferrer">Amazonで見る</a>

        <a class="media-card-x-btn media-card-x-btn-secondary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD/">関連記事</a>

      </div>

    </div>

  </div>


  <div class="media-card-x">

    <div class="media-card-x-image">

      <img alt="批評テレビ" src="https://images-na.ssl-images-amazon.com/images/P/B0G1T5GVJD.09.MAIN._SCRMZZZZZZ_.jpg">

    </div>

    <div class="media-card-x-body">

      <div class="media-card-x-title">批評テレビ</div>

      <div class="media-card-x-text">君は酷の涙を見る</div>

      <div class="media-card-x-actions">

        <a class="media-card-x-btn media-card-x-btn-primary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD" target="_blank" rel="noopener noreferrer">Amazonで見る</a>

        <a class="media-card-x-btn media-card-x-btn-secondary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD/">関連記事</a>

      </div>

    </div>

  </div>

  <div class="media-card-x">

    <div class="media-card-x-image">

      <img alt="批評テレビ" src="https://images-na.ssl-images-amazon.com/images/P/B0G1T5GVJD.09.MAIN._SCRMZZZZZZ_.jpg">

    </div>

    <div class="media-card-x-body">

      <div class="media-card-x-title">批評テレビ</div>

      <div class="media-card-x-text">君は酷の涙を見る</div>

      <div class="media-card-x-actions">

        <a class="media-card-x-btn media-card-x-btn-primary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD" target="_blank" rel="noopener noreferrer">Amazonで見る</a>

        <a class="media-card-x-btn media-card-x-btn-secondary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD/">関連記事</a>

      </div>

    </div>

  </div>


  <div class="media-card-x">

    <div class="media-card-x-image">

      <img alt="批評テレビ" src="https://images-na.ssl-images-amazon.com/images/P/B0G1T5GVJD.09.MAIN._SCRMZZZZZZ_.jpg">

    </div>

    <div class="media-card-x-body">

      <div class="media-card-x-title">批評テレビ</div>

      <div class="media-card-x-text">君は酷の涙を見る</div>

      <div class="media-card-x-actions">

        <a class="media-card-x-btn media-card-x-btn-primary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD" target="_blank" rel="noopener noreferrer">Amazonで見る</a>

        <a class="media-card-x-btn media-card-x-btn-secondary" href="https://www.amazon.co.jp/dp/B0G1T5GVJD/">関連記事</a>

      </div>

    </div>

  </div>


</div>

🧠トレーニング損失が継続的に減少し、検証損失が増加する傾向が見られる場合、それは過学習の兆候です。

 トレーニング損失が継続的に減少し、検証損失が増加する傾向が見られる場合、それは過学習(オーバーフィッティング)の兆候です。これを理解するために、まず損失の概念と過学習が何を意味するかを明確にしましょう。

損失関数(Loss Function)

  • 損失関数は、モデルの予測がどの程度実際のデータポイントから離れているかを数値化するものです。

  • モデルのトレーニングでは、この損失を最小化するようにモデルのパラメータを調整します。

  • トレーニング損失は、トレーニングデータに対するモデルのパフォーマンスを示します。

過学習(Overfitting)

  • 過学習は、モデルがトレーニングデータのパターンやノイズに過剰に適合してしまい、新しいデータに対する一般化能力が低下する現象です。

  • モデルが複雑すぎる、またはトレーニングデータが限られている場合に発生しやすい。

トレーニング損失と検証損失の関係

  • トレーニング損失が減少するのは、モデルがトレーニングデータに対してより良い予測を行うようになっていることを意味します。

  • しかし、同時に検証損失が増加する場合、これはモデルが検証データ(トレーニングに使用されていないデータ)に対して悪い予測をしていることを示しています。つまり、モデルがトレーニングデータに特化しすぎて、新しいデータに対して適切に動作しない状態です。

過学習の例

  • 例えば、ある試験の問題と答えを丸暗記する学生を考えてみましょう。この学生はその試験では高得点を取るかもしれません(トレーニング損失が低い)。しかし、同じ内容で少し言い回しを変えた新しい問題に直面したとき、彼は上手く答えられないかもしれません(検証損失が高い)。これは、学生が問題の本質を理解するのではなく、単に特定の問題に過剰に適合してしまったためです。

結論

トレーニング損失と検証損失のこのような動きは、モデルがトレーニングデータには適合しているが、それが一般化されていないことを示しています。そのため、モデルの複雑さを調整する、データを増やす、正則化を加えるなどの手段で過学習を防ぐ必要があります。


画像
A minimalist, 1960s psychedelic-style illustration depicting a marathon runner overtraining, with modifications. The runner, depicted in a simple, stylized form, now has exaggerated visual elements like spirals and waves emanating from their back instead of the rear, emphasizing the concept of overtraining. The image maintains bold, swirling patterns and vibrant, yet faded colors, characteristic of pulp printing. The overall palette is subdued, with pastel tones and a slightly washed-out look to mimic the look of aged ink.

🚫eval関数がどれだけ危険だというのか?

 

危険と言われているのはEVAL Injection 動的評価コードにおける「ディレクティブの不適切な中和」が原因とされる

ソフトウェアが上流コンポーネントから入力を受け取るが、動的評価呼び出し(evalなど)で入力を使用する前にコード構文を中和(neutralizes)していない、または誤って中和している。

中和とはこういうやつか

インジェクションの問題は、多種多様な問題を含んでいます。このため、これらの弱点について議論する最も効果的な方法は、それらをインジェクションの弱点として分類する明確な特徴に注目することです。最も重要な問題は、すべてのインジェクション問題には共通点があるということです--すなわち、制御プレーンのデータをユーザーが制御するデータプレーンにインジェクションすることができるということです。
つまり、正当なデータ・チャネルを通してコードを送り込むことで、プロセスの実行を変更することができるのです。
バッファオーバーフローや他の多くの欠陥が、実行を得るために何らかの問題をさらに利用することを伴うのに対し、インジェクション問題はデータを解析するだけでよい。このカテゴリーの弱点の最も古典的な例は、SQLインジェクションとフォーマット文字列脆弱性である。

https://cwe.mitre.org/data/definitions/94.html

たくさんあるインジェクション

CVE-2022-2054
Python コンパイラが eval() を使って悪意のある文字列を Python コードとして実行する
CVE-2021-22204
チェーン: EXIF プロセッサコードの正規表現が文字列の終端を正しく決定しておらず (CWE-625)、eval インジェクション (CWE-95) を可能にしていました。
CVE-2021-22205
連鎖: バックスラッシュの後に改行が続くと、検証ステップ(CWE-20)がバイパスされ、evalインジェクション(CWE-95)が可能になる。
CVE-2008-5071
PHP プログラムにおける eval インジェクション。
CVE-2002-1750
Perl プログラムにおける eval インジェクション。
CVE-2008-5305
Perl プログラムにおける、ハイフンと数字のみを含むべき ID を使用した Eval インジェクション。
CVE-2002-1752
Perl の eval 関数へのダイレクトコードインジェクション。
CVE-2002-1753
Perl プログラムへの eval インジェクション。
CVE-2005-1527
Perl eval 関数へのダイレクトコードインジェクション。
CVE-2005-2837
Perl eval 関数への直接コードインジェクション。
CVE-2005-1921
MFV. ネストされるべきではないネストされた構造を使用した、PHP eval 文へのコードインジェクション。
CVE-2005-2498
MFV. ネストされるべきではないネストされた構文を使用した、PHP eval 文へのコードインジェクション。
CVE-2005-3302
フォーマットされたファイルのフィールドから Python の eval 文へのコードインジェクション。
CVE-2007-1253
Python プログラムにおける eval インジェクション。
CVE-2001-1471
チェーン: eval インジェクションの結果。無効な値によって変数の初期化が妨げられ、攻撃者によって変更され、 後で PHP の eval 文にインジェクションされる可能性があります。
CVE-2007-2713
チェーン: リダイレクト後の実行が eval インジェクションを誘発する。

javascriptではハッキリと「eval() は危険だから使わないでください!」とまで言っている。

eval() は呼び出し元の権限で渡されたコードを実行する危険な関数です。悪意のある第三者に影響を受ける可能性のある文字列で eval() を実行すると、あなたのウェブページ / 拡張機能の権限でユーザーのマシン上で悪意のあるコードを実行してしまう可能性があります。

たばこの注意書きのようにあからさま、じゃなぜ存在するんだ?必要悪?

たばこの煙は、あなたや周りの人が肺がん、虚血性心疾患、脳卒中になる危険性を高めます。

https://www.marlboro.jp/login.html?resource=%2Fcontent%2Fpmj%2Fmarlboro%2Fhome.html&$$login$$=%24%24login%24%24&j_reason=unknown&j_reason_code=unknown

eval「俺に触れるんじゃねえ」( 力を封印している)

ほとんど、「あなたの事食べちゃうから逃げなさい」という森のくまさんのような矛盾した存在のeval。もしくは自意識過剰。

主人公が森を出る途中にばったりと熊に出会い、(お互いに見合ってという部分がある歌詞もある)君は逃げないのか? 銃を持っていないようだけどと熊から言われて、主人公が走り出して熊が追いかけてくる。

「漆黒の翼」というキャラを演じる、「中二病」の男子生徒。オカルト部所属。水色の髪に小柄で華奢な体格が特徴で、腕にはファッションで包帯を巻く(本人曰く力を封印している)。

そもそもの話、LISPから登場したeval

LISPはevalが最初に登場した言語である。evalの実装によって、最初のLISPインタプリタが現れたのである。それ以前は、LISPの式はコンパイルされていた。しかし一度evalが実装されると、それは単純な入力・評価・出力のループ (REPL) の一部として使われるようになり、最初のLISPインタプリタの基礎を形作った。LISPの後のバージョンのevalはコンパイラとしても実装されている。

悪いのはEvalなんだろうか?

Rubyはevalにスコープ要素を入れることで何かを免罪(包帯をまく)しようとしている。

重要な点として、IASマシンはプログラムとデータをひとつのメモリに混在させることを意図したほぼ最初の設計である。

MDNではfunctionを代わりにつかってくれという。

function looseJsonParse(obj){
   return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
  "{a:(4-1), b:function(){}, c:new Date()}"
))

人々はなぜこれほどまでに危険といわれているevalを後世に残そうとするのか?

私達は火薬庫の中を静電気にすら注意して歩くのに、アンタたちはタバコをフカして歩けと言う。

https://amzn.to/3Gso611

LISPについては、bootstrap問題の解消ということがある。

ブートストラップ問題 (Bootstrap problem) は、コンパイラをコンパイル対象のプログラミング言語で作成した際に、そのコンパイラの最初のコンパイルをどうするかといった場合を典型的な例とする、いわゆる「鶏と卵」の形をしたセルフホスティング環境の問題を指す。これを解決するための方式をブートストラップ方式といい、この問題を何とかして最初の完備した環境を作ることをブートストラッピングという

コンパイラをコンパイラコンパイラゆうてもーキー

この本によるとjavascriptはScheme(LISP系)に影響を受けているからそのままevalも引き継いだのかもしれない

evalについても前向きに書いてある。ブレンダンアイク(通称剃刀アイク)師匠は語る

完全な動的スコープというのは入れてませんでした。ストールマンはEmacsにとって重要なものだとこだわって、Elispをそれで満たしましたが。Javascriptは概ね静的スコープを持ち、多少変則的なところがあります。非常に動的になる抜け穴があるのです。グローバルオブジェクトと、with文と、evalです。しかしmy以前のPerlのダラー変数や、Tclのupvarやuplevelみたいなのとは違います。90年代にはそんなのがたくさんあって、流行だったのです。(ブレンダン・アイク coders at workP138)

この短時間にevalの可能性をemacsとperlをディスりで挟み込むという抜群な切れ味を見せる剃刀アイク先輩。しかし、どういうつもりでjsにeval関数が残っているかは、そのあとの影響を受けた言語などからもわかる。あと創始者が認めてもmdnはevalを即廃止したい勢い。


Netscapeの経営陣はすぐに、アイクがJavaに似た構文を持ち、Schemeや他の既存のスクリプト言語に似ていない新しい言語を考案することが最良の選択肢だと判断しました。

いいぞ、ネスケ経営陣。英断だ

(define (eval-with-x prog a b)
 (let ((at-a (eval `(let ((x ',a)) ,prog)))
       (at-b (eval `(let ((x ',b)) ,prog))))
   (- at-b at-a)))

C言語にはevalはない、それはなぜか

LISPの流れをくまない限り、みんなSHELLにEVALを参考にしてevalを組み込んだのだろうか、そして、shellほど権限やコンテクストがしっかりしていないので、evalを使うなと生み出しておいて君たちは後から危険だと言うのか。シザーハンズ

C言語にはeval関数が直接的に存在しないのにはいくつかの理由が考えられます。

  1. 低レベル言語の性質: Cは低レベルの言語であり、メモリ管理や直接的なハードウェアアクセスが可能です。このような言語において、ランタイム時に任意のコードを動的に評価・実行するevalのようなメカニズムは、安全性の観点からリスクが高いです。

  2. コンパイル方式: Cはコンパイル言語であり、ソースコードは実行前に機械語にコンパイルされます。evalは通常、インタプリタ言語で頻繁に使用される機能であり、ランタイム時に動的にコードを解釈・実行することが容易なインタプリタの特性と相性が良いです。

  3. 複雑性evalを適切に実装するには、Cのランタイムにコンパイラやインタプリタの一部を組み込む必要があります。これは非常に複雑で、Cのシンプルさや効率性に影響を与える可能性があります。

  4. 安全性: 上述したように、evalを使用すると任意のコードが実行されるため、セキュリティ上のリスクが高まります。不正なコードや意図しない動作を引き起こす可能性があるため、特に低レベル言語のCにおいては、このような機能が避けられることが多いです。

  5. 特定の目的: C言語は主にシステムプログラミングや組み込みプログラムの開発のために設計されました。このような用途では、evalのような動的コード実行機能はあまり求められないことが多いです。

もちろん、特定の状況や要求に応じて、Cで自前のevalのような機能を実装することは技術的に可能です(例: 外部のコンパイラを呼び出してコードをコンパイル・実行する)。しかし、C言語の設計思想や用途を考慮すると、標準ライブラリにevalが含まれていないのは理解しやすいでしょう。

Phpは警告レベルで非推奨、でもちゃあんと使えるけどね

警告
eval() は非常に危険な言語構造です。 というのも、任意の PHP コードを実行できてしまうからです。 これを使うことはおすすめしません。 いろいろ検討した結果どうしても使わざるを得なくなった場合は、細心の注意を払って使いましょう。 ユーザーから受け取ったデータをそのまま渡してはいけません。 渡す前に、適切な検証が必要です。

Perlは禁止することはないみたいだった。

さすがラクダのperl。ね、なんでもできるでしょ、といった感じ