のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

AWS Cloud9 の デバッグ機能をさわってみる

今回は AWS Cloud9 のデバッグ機能の基本的な使い方をまとめたいと思います。

AWS Cloud9は、ブラウザのみでコードを記述、実行、デバッグできる統合開発環境 (IDE) です。

aws.amazon.com

Cloud9 には、あらかじめ AWS CLIAWS SAM、AWS CDK などの 主要な AWSコマンドラインツールや、主要なプログラミング言語のランタイム、Git や Docker もインストールされており、短時間で環境をプロビジョニングできるので、私も重宝してます。

この Cloud9 でデバッグをサポートしているプログラミング言語は、次のドキュメントに記載されています。

docs.aws.amazon.com

Python や Node.js、PHPJava などがサポートされていますね。

今回は、Python のシンプルなプログラミングを使用してデバッグ機能を試していきます。

なお、この記事の内容は 2022年 12月に検証した内容を基にしています。


今回、デバッグ機能を適用する Python のコードです。

def add(num1, num2):
    return num1 + num2

a = 2
b = 8
result = add(a,b)
if result == 10:
    print('ten!')
print(result)

最初に addという足し算を行う関数を定義し、それを呼出し、結果が 10かどうかを確認します。10なら ten! というメッセージを表示しますが、10以外なら表示しません。そして最後に足し算の結果を表示します。非常にシンプルですね。

これを Cloud9 で calc.py というファイルに保存しておきます。


ブレークポイントの設定

では、この calc.py のコードにブレークポイントを設定してみます。

ブレークポイントを設定すると、デバッグ実行時にその設定したコードでいったん停止して、変数の状況などを確認できます。

Cloud9 では、行番号の左側をクリックすることで、ブレークポイントの設定や解除が行えます。

今回は、下図のように 4 行目 の a = 2 のコードに設定します。設定すると、ピンク色の丸印がつきます。

ブレークポイントの設定


デバッグ実行

次にデバッグ実行をしていきます。Cloud9 でデバッグ実行していく方法はいくつかありますが、今回は手っ取り早く実行する方法を紹介します。

まず、Cloud9 のメニューで Run をクリックして、デバッグではない通常の実行を行います。

すると Cloud9 の画面下部に結果が表示されますが、その中に 虫のアイコン が表示されているので、それをクリックして虫アイコンに色がついた状態にします。

このクリックにより、calc.py の実行をデバッグモードに切り替えることができます。

デバッグモードに設定

その後、再び Run メニューをクリックすると、デバッグモードで実行することができます。


Step Overと変数の内容の表示

デバッグ実行すると、ブレークポイントを設定した 4 行目の a = 2 で 実行が停止状態になります。

この状態で、Cloud9 の画面の右側に表示されている Debugger メニューをクリックします。

Debugger メニューをクリックすると、下図のようなペインが表示されます。

このペインの上にある、Step Over のメニュー(下図赤枠の部分)を1回クリックします。

するとブレークポイントで停止していた実行が1行進みます。これで ブレークポイントの 4 行目のコードの実行が完了した状態になります。

このように、ブレークポイントで実行をいったん停止し、1行づつコードを実行していくことを一般的に ステップ実行 などといいます。

また、下図の赤線部分をみると、変数 a には 2 という int 型の値が格納されていることがわかります。

このように、ブレークポイントでコードの実行をいったん停止したあとに、 Step Overでコードをステップ実行しながら変数の内容を確認していくことができます。

Step Over のメニューのクリックを続けてみましょう。すると 5 行目から 9行目まで 1行づつ実行され、デバッグ実行が完了しましたね。

ただ、1行目、2行目に定義されている add 関数のコードにステップ実行ができませんでした。

実は、Step Over では、呼び出している関数の内部のコードにステップ実行することができません。

それを行うには、Step IntoStep Into という操作を行います。


Step IntoとStep Out

では、Step IntoStep Out を試してみましょう。

もう一度 Run メニューをクリックして 4 行目のブレークポイントで停止します。

その後、6 行目まで、Step Over でステップ実行を続けます。

6 行目では add 関数を呼び出していますね。ステップ実行が 6 行目きたら、下図のように Step Intoのメニューをクリックします。

すると、ステップ実行が 2行目に進みましたね。

このように、呼び出し先の関数にステップ実行を進めるには、Step Into を行います。

また、呼び出し先の関数から、呼び出し元のコードにステップ実行を戻すには、Step Out を行います。

下図のように、ステップ実行が 2行目に進んだ状態で、Step Out のメニューをクリックします。

Step Outすると、下図のようにステップ実行が 7行目になりましたね。呼び出し元のコードに戻って、ステップ実行を続けることができます。


Resume と Stop

デバッグ実行中、ステップ実行ではなく、一気にコードを実行したい場合は、Resume メニューをクリックします。

これにより、次のブレークポイントが設定されていれば、そこまで一気にコードを実行できます。

また、デバッグ実行を途中で停止したい場合は画面下部にある Stop をクリックします。

これにより、ステップ実行の途中でもデバッグ実行を停止できます。


最後に

今回は、Cloud9 のデバッグ機能の基本的な使用方法についてまとめました。

Cloud9 のデバッグ機能は、他にも様々な使い方ができますので、下記のドキュメントを参考にしてみて下さい!

docs.aws.amazon.com

モダンなJavaScriptのお勉強:アロー関数編

ひさびさに モダンな JavaScript のお勉強ネタを書きます。

今回は、アロー関数について勉強しています。 アロー関数は、ES2015から追加された関数の記述方法の一つです。

まず、従来の関数の記述方法をおさらいしておきましょう。

次のように、function のあとに関数名、そして( ) で囲んだ引数名を指定し、関数の処理は { } で囲みます。

function sayHello(yourname) {
    return "Hello! " + yourname;
}

console.log(sayHello("Nobe"));

このコードを実行すると、次のようになります。

結果:

Hello! Nobe

また、次のように関数を変数に代入して扱うこともできます。

const hellofunc = function sayHello(yourname) {
    return "Hello! " + yourname;
}
console.log(hellofunc("Nobe"));

このコードの実行結果は、最初のコード例と同じです。

結果:

Hello! Nobe

では、アロー関数の記述方法をみていきます。

アロー関数では、関数自体に名前を付けず、いきなり引数から記述するのが特徴です。

次の例では、(yourname) が関数の引数を表しています。 その後に => と記載し、関数内の処理を { }内に記載します。

(yourname) => { 
    return "Hello! " + yourname;
}

つまり、yourname という引数を受け取り、それに Hello という文字列を連結して return するという関数になります。 関数の名前はありませんが、次の例のように変数に代入して、変数名で呼び出すことができます。

const hello_arrow1 = (yourname) => { 
    return "Hello! " + yourname;
}
console.log(hello_arrow1("Nobe1"));

結果:

Hello! Nobe1

まずは、(引数) => { 関数の処理 } という基本形を覚えておくとよいでしょう。

ただ、アロー関数では、省略した記述ができるケースがあります。 例えば、引数が1つの場合は、次のように引数を囲んでいる ( )を省略できます。

// 引数が1つの場合は、() を省略できる
const hello_arrow2 = yourname => { 
    return "Hello! " + yourname;
}
console.log(hello_arrow2("Nobe2"));

結果:

Hello! Nobe2

逆にいうと、引数が複数の場合は、引数を囲む ( )は必須になります。

// 引数が複数の場合は、() が必要
const hello_arrow3 = (yourname,youraddress) => { 
    return "Hello! " + yourname + " in " + youraddress;
}
console.log(hello_arrow3("Nobe3","Kyoto"));

結果:

Hello! Nobe3 in Kyoto

その他の省略可能なルールとして、次の例をみてみましょう。

// 関数の処理が単一行でその結果をreturnする場合は、{} と return 句を省略できる
const hello_arrow4 = yourname => 
  "Hello! " + yourname;
console.log(hello_arrow4("Nobe4"));

結果:

Hello! Nobe4

本来は関数の処理として { return "Hello! " + yourname; } と記述するのですが、処理が単一行であれば、関数の処理を囲む { }return 句を省略できるので、このような記述になるわけです。

逆にいうと、処理が複数行になる場合は、次のように 関数の処理を囲む{ }は必須で、関数が値を返す場合は return 句も必要になります。

// 関数の処理が複数行になる場合は、{}が必要。return 句は省略できない
const hello_arrow5 = yourname => {
  const greeting = "Hello! ";
  return greeting + yourname;
}
console.log(hello_arrow5("Nobe5"));

結果:

Hello! Nobe5

次に、オブジェクトのように複数行を return する場合をみてみましょう。 この場合、return する値を ( ) で囲むことで、そのオブジェクトを return することになります。

// returnする内容が複数行になる場合は、() で囲む
const hello_arrow6 = (yourname,youraddress) => (
     {
        name:    yourname,
        address: youraddress
     }
)
console.log(hello_arrow6("Nobe6","Kyoto"));

結果:

{ name: 'Nobe6', address: 'Kyoto' }

まとめ


JavaScript ではなく、Java 言語のラムダ式をご存じの場合は、このアロー関数がよく似ていると感じるでしょう。 JavaScript のアロー関数にせよ、Java 言語のラムダ式にせよ、基本的な記述方法がわかっていれば、コードを読み解くことは難しくありません。 アロー関数では、基本的に => があれば、その左にあるものは引数、右にあるものが関数の処理本体として読み解くと良いでしょう。

モダンなJavaScriptのお勉強:テンプレート文字列編

今回は、テンプレート文字列を試してみます。

ES2015から、テンプレート文字列を使用して、文字列を構成できるようになっています。

例えば文字列を連結する場合、従来は次のような方法で行っていました。

const firstName = "のべ";
const lastName = "てつお";
const address = "京都";
const  printFormat="氏名: " +  firstName + " " +  lastName + "\n" + "住所: " + address;
console.log(printFormat);

結果:

氏名: のべ てつお
住所: 京都 

テンプレート文字列を使うと、次のように記述できます。

const firstName = "のべ";
const lastName = "てつお";
const address = "京都";
const  printFormat= `氏名: ${firstName} ${lastName} \n住所: ${address}`;
console.log(printFormat);

結果:

氏名: のべ てつお 
住所: 京都

同じ結果にできましたね。 テンプレート文字列では、 ` つまりバッククォートで文字列を囲みますが、その中の ${ } で囲んだ部分には JavaScript の変数や処理結果を埋め込むことができます。

上の例の ${firstName} では、firsrName 変数を埋め込んでいるのでその値が出力できます。

たくさんの + 演算子を使って連結するよりもシンプルで、可読性も向上できそうですね。

${ } で囲んだ部分には JavaScriptの処理も書けるので、試しに次のようなコードを実行してみましたが、期待通り 1100円と出力できました。

function getTaxRate() {
    return 0.1;
}

const productPrice = 1000;
const  priceFormat= `税込み価格 ${productPrice + (productPrice * getTaxRate())} 円`;
console.log(priceFormat);

結果:

税込み価格 1100 円

まとめ

  • テンプレート文字列を使うことで、+ 演算子を用いた文字列の連結によりもシンプルで読みやすいコードを記述できます。
  • テンプレート文字列は、` (バッククォート)で囲みます。この中で、${ }で囲まれた部分には JavaScriptを記述し、変数や動的な値を出力できます。

モダンなJavaScriptのお勉強:分割代入編

今回は、分割代入 についてまとめます。

代入とは、変数への値を設定することです。 例えば、JavaScript で次のようなオブジェクトがあるとします。

const customer = {
    id:       1,
   name:  "のべ",
   email:  "xxx@nobelabo.net"
};

この customer オブジェクトから name と email プロパティを取り出して変数に格納したいとします。 分割代入を使わない場合は、次のようになります。

let name = customer.name;
let email  = customer.email;
console.log(name);
console.log(email);  

結果:

のべ
xxx@nobelabo.net

2つの変数を別々に用意して、それぞれ、オブジェクト名.プロパティ名 を指定して代入していますが 分割代入を使うと、もっとシンプルに変数に値を代入できます。 では、分割代入を使って同じことをやってみましょう。

let  { name,  email }  = customer;
console.log(name);
console.log(email);  

結果:

のべ
xxx@nobelabo.net

いかがでしょう?

変数宣言で、{ } で囲って複数の変数を指定しています。 これらの変数に、customer のプロパティ名と一致している値が代入されています。 この例では { name, email } という順で指定していますが、{ email, name } のように順番が変わっても大丈夫です。 少しシンプルにできましたね。

次に、変数名を代入元のオブジェクトのプロパティ名と違うものにする方法をみてみましょう。

let  { name: customerName,  email: customerEmail }  = customer;
console.log(customerName);
console.log(customerEmail);  

結果:

のべ
xxx@nobelabo.net

変数宣言時に、{プロパティ名: 任意の変数名 } とすることで実現できますね!

この分割代入ですが、オブジェクトだけでなく配列でも使用できます。 配列の場合は、変数を [ ] で囲みます。

const  colors = ["Red", "Blue", "Yello"];
let  [  red,  blue ]  = colors;
console.log(red);
console.log(blue);  

結果:

Red
Blue

ただし配列の分割代入の場合、配列の要素順にしか値を代入できません。 例えば、次のようなコードにすると、blue 変数には 文字列 "Red" が、red 変数には 文字列 "Blue" が代入されますのでご注意ください。

const  colors = ["Red", "Blue", "Yello"];
let  [  blue,  red ]  = colors;
console.log(red);
console.log(blue);  

結果:

Blue
Red

まとめ

  • オブジェクトの分割代入では、{ } 内でオブジェクトのプロパティ名を指定すれば、順序に関わらず代入できることがわかりました。
    • プロパティ名と同じ変数名にすることも、任意の変数名にすることもできましたね。
  • 配列の分割代入では、{ } 内で任意の変数名を指定して代入できますが、あくまで配列の要素順で代入されることに注意しましょう!

モダンなJavaScriptのお勉強:変数宣言編

これまでは、普通に var を使って変数宣言していましたが、ECMAScript 2015 で追加された letconst を使って、その違いを確認してみます。

var の場合

例えば、次のような宣言をしてみます。

var message = "Hello";

この変数 message は、値の変更がでます。変数だから当然と言えば当然かもですが。

message = "Hi";
console.log(message);

結果

Hi

また、同じ変数名で再度宣言することもできます。

var message = "ハロー";
console.log(message);

結果

ハロー

let の場合

letの場合は、値の変更は可能ですが、同じ変数名での再宣言は不可になります。

まず let で宣言します。

let message = "Hello";

その後、値を変更します。次のコードは正常に実行できます。

message = "Hi";
console.log(message);

結果

Hi

ただし、次のように再宣言するコードはSyntaxErrorになり、実行できません。

let message = "ハロー"; // SyntaxError
console.log(message);

const の場合

constは、値の変更も、同じ変数名での再宣言も不可になります。

いわゆる 定数 の扱いですね。

const で宣言してみます。

const message = "Hello";
console.log(message);

その後、値を変更します。次のコードはSyntax Errorにはなりませんが、実行時にエラーになります。

message = "Hi";
console.log(message);

発生したエラーは、TypeError: Assignment to constant variable でした。

また、let と同じく次のように再宣言するコードはSyntaxErrorになり、実行できません。

const message = "ハロー"; // SyntaxError
console.log(message);

const は、値の変更が不可という事がわかりましたが、1つ注意点があります。

値が不可なのは、文字列 ( String ) や 数値 ( Number) や 真偽 ( Boolean) などのプリミティブ型であり、オブジェクトのプロパティや配列の要素は変更できます。

オブジェクトのプロパティの例をみてみましょう。

次のコードは const でオブジェクトを宣言していますが、そのプロパティは変更可能です。

const member1 = {
     id: 1,
     name: "Neco",
     address: "Tokyo"
};
member1.address = "Osaka";
console.log(member1);

結果

{ id: 1, name: 'Neco', address: 'Osaka' }

配列の要素の例もみてみましょう。このコードでも const で宣言した配列の要素を変更しています。

const mode = ["PLAY", "STOP"]
mode.push("PAUSE");
console.log(mode);

結果

[ 'PLAY', 'STOP', 'PAUSE' ]

まとめ

var と違い、letconst は同じ変数名での再宣言は不可であることがわかりました。

再宣言は、コードが混乱する元になりがちなので、基本的に letconst での変数宣言が良さそうです。

また、letconst の使い分けは、変数として扱うか、定数として扱いかで考えればいいですね。

/* -----codeの行番号----- */