1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

コンテキストの生成と消滅が、遊戯王のチェーン処理みたいだと思った話

Last updated at Posted at 2022-04-14

はじめに

こんにちは、Ebataです。

この記事は遊戯王で遊んだことがあり、かつコールスタック内でのコンテキストの生成や消滅タイミングの理解が難しい、という狭すぎるターゲット層に届けたい記事です。

技術書を読んでいる時に、「あれ、なんか見たことあるなぁ」と思ったので共有いたします。(これTwitterでも良くない?)

コンテキストとは

そもそも、「コンテキストって何?」という方に向けて、簡単に解説します。

プログラミングの分野でも、同じコード記述やプログラム上の要素が、その置かれているプログラム内での位置や、実行される際の内部状態などによって異なる振る舞いをしたり、異なる制約を受けたりすることを指してコンテキストということがある。

『IT用語辞典 e-Words』より

つまり同じコードでも、環境が違えば違うルールのもとで実行される、ということですね。

記事内でのコンテキストは、このルール・制約のことを指しています。

コールスタックとは

関数内で他の関数を呼び出すときの階層です。

例えば、

script.js
function first(){
  second();
}

function second(){
  third();
}

...

first(); //関数を呼び出す

このようなコードがあった場合、first()second()を呼び出して、second()third()を呼び出して……。

といったように、階層的に表すことができます。これをコールスタックと言います。

コールスタックとコンテキストの関係

「コールスタックとコンテキストはなんとなく分かった。で、どういう関係なの?」

階層表示された関数ごとに、コンテキストが存在する。ということです。変数は参照できるか、などの制約が変わります。

一番分かりやすいのは、thisが何を参照するのか、ではないでしょうか。

script.js
//グローバルコンテキストでは、thisはwindowを参照。
console.log(this === window);
> true

//メソッドコンテキストでは、ichiroを参照。
const ichiro = {
  name: "一郎",
  hello: function(){
    console.log("こんにちは、" + this.name);
  }
}

ここで、この記事の内容です。

コールスタックでは、呼び出された順番にコンテキストが生成されます。

script.js
function first(){
  second();
}

fuction second(){
  third();
}

function third(){
  //処理
}

first();

この時、

  1. first()のコンテキスト生成
  2. second()のコンテキスト生成
  3. third()のコンテキスト生成
  4. third()のコンテキスト消滅
  5. second()のコンテキスト消滅
  6. first()のコンテキスト消滅

といった流れになります。

遊戯王のチェーン処理

ここからは本当に関係ないのですが、先述したコンテキストの生成・消滅の流れが「遊戯王のチェーン処理」に似ていると感じた話です。

遊戯王には、攻撃や効果の発動に対して効果を発動する、「チェーン」と呼ばれる処理があります。

例えば、モンスターの攻撃に対してトラップカードを発動し、そのトラップカードに対してトラップカードを発動することが可能です。

yugioh.js
//ライフポイントは8000。
my_life = 8000;
enemy_life = 8000;

//攻撃に対して発動するトラップカード。
const magic_cylinder = {
  name: "マジックシリンダー",
  type: "トラップカード",
  effect: function(){
    /*
    相手モンスターの攻撃宣言時、攻撃モンスター1体を対象として発動できる。
    その攻撃モンスターの攻撃を無効にし、その攻撃力分のダメージを相手に与える。
    */
  }
}

//トラップカードに対して発動するトラップカード。
const solemn_judgment = {
  name: "神の宣告",
  type: "トラップカード",
  effect: function(){
    /*
    LPを半分払って以下の効果を発動できる。
    魔法・罠カードが発動した時に発動できる。
    その発動を無効にし破壊する。
    */
  }
}

//攻撃するモンスター。
const blue_eyes_white_dragon = {
  name: "ブルーアイズホワイトドラゴン",
  type: "通常モンスター",
  atk: 3000,
  def: 2500
}

function kougeki()=>{
  //攻撃する。
}

//攻撃後の処理。
function attack(monster){
  //①monsterが攻撃する。
  kougeki();
  //②マジックシリンダーの発動。
  magic_cylinder.effect;
  //③神の宣告の発動。
  solemn_judgment.effect;
}

//ブルーアイズの攻撃。
attack(blue_eyes_white_dragon);

長々と書きましたが、

  1. ブルーアイズホワイトドラゴンの攻撃。
  2. マジックシリンダーの効果発動。
  3. 神の宣告の効果発動。

この順番で発動され、

ブルーアイズホワイトドラゴンの攻撃を、マジックシリンダーで無効にし跳ね返す。この処理を神の宣告でさらに無効にする、という流れになります。

なので、このチェーン処理の順番は、

  1. 神の宣告の効果でマジックシリンダー無効。
  2. マジックシリンダーは無効される。
  3. ブルーアイズホワイトドラゴンの攻撃が通る。

となります。

この流れが、先述した『コールスタックでのコンテキスト生成・消滅のタイミング』に似ていますよね。

遊戯王をやっている方は、こう考えていただけると分かりやすいと思います。

終わりに

全然内容はありませんでしたが、個人的には大満足の記事になりました。こんな記事も誰かに読んでいただけたなら嬉しいです。

あと、まだ駆け出しなのでコードが汚いとかはご愛嬌。。。(成長します)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?