順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

JavaScriptにおけるthisの違いについて

気になる記事を発見。

JavaScriptの「this」は「4種類」?? - Qiita

とりあえず下記の3種類について調べてみた。

まずは違いを分かりやすくするためにソースを書いてみる。

メソッド呼び出しパターン

  var testObj = {
    
    //Javaでいうとフィールドのイメージ
    value:100,
    
    //Javaでいうとメソッドのイメージ
    testMethod:function(){
      
      //メソッド内でthisを呼んでいるので100が出力される
      //thisはtestObjを指している
      console.log("method:" + this.value);
    }
  }

メソッドの中でthisを呼んでいるのでこの場合のthisはtestObjを指している。
なので、this.valuetestObj.valueが同じ意味になる。

関数呼び出しパターン

var value = 300; //グローバル変数

/* ~~ 途中の処理省略 ~~*/
  
  //関数
  function hoge(target){
    
    //関数呼び出しの場合はグローバル変数のvalue
    //インスタンスを生成した場合はインスタンス固有のvalue
    this.value;
    console.log(target + this.value);
    //console.log(target + this);
  }

/* ~~ 途中の処理省略 ~~*/

  //関数呼び出し
  hoge("function1:");

関数の中でthisを呼び出しているのでこの場合のthisはグローバルオブジェクトとなる。
なので、関数内のthis.valueグローバル変数となり、300が出力される。

f:id:sndstudy:20151208231609p:plain

開発者ツール(F12)で調べると
Windowオブジェクト(グローバルオブジェクト)の中にvalueがあることが分かる。

コンストラクタ呼び出しパターン

  //関数
  function hoge(target){
    
    //関数呼び出しの場合はグローバル変数のvalue
    //インスタンスを生成した場合はインスタンス固有のvalue
    this.value;
    console.log(target + this.value);
    //console.log(this);
    
  }
  
  //メソッド呼び出し
  testObj.testMethod();
  
  //インスタンス生成
  //valueを定義していないのでundefinedが出力される
  var instanceHoge = new hoge("instance1:");
  
  //関数呼び出し
  hoge("function1:");
  

インスタンスを生成した場合(new)、生成時はthis.valueの中に値を定義
していないのでundefinedが出力される。
これは生成したインスタンス内のvalue
グローバル変数valueという違いがあるので出力結果が異なるのだと思う。


とりあえず違いとしてはなんとなく分かった気がする。
時間があればapply,call呼び出しパターンについても調べてみようと思う。

JJUG CCC 2015 Fallに参加してきた

JJUG CCC 2015 Fallに参加してきた。

聴いてきた講演は

  1. 基調講演1: 「Javaは守りに入らない、これが今のJavaだ」
  2. 基調講演2: Java EE 8 – Work in Progress
  3. 苦手克服!例外スタックトレースから読み解くバグ
  4. Reactive Webアプリケーション – そしてSpring 5へ
  5. これからのコンピューティングの変化とJava
  6. Garbage First Garbage Collector (G1 GC)

このうち、2・3・4について少しだけまとめたいと思う。


※ちなみに1はJJUG CCC 2015 Fallの説明とJavaOne2015の報告などなど
 5は前日の飲み会の疲れがピークに達し意識が飛んだので
 まとめられる程のメモを取れなかった
 6は知識不足で内容が理解できなかった
 (おそらくGCの種類の話とG1GCの使い所の話だと思う)

基調講演2: Java EE 8 – Work in Progress

JavaEE8で実装される予定の機能を説明していた。

JSON-Binding1.0

オブジェクトをJSONに変換したり、JSONをオブジェクトに変換できる機能。
この機能により、GSONとかJSONICを使用しなくても変換が可能になるらしい。
ライブラリ不要でJSONに変換できるのはいいかも。

JSON-Processing1.1

JSONの値に直接アクセスできるJSON-Pointerという機能が新しく追加する。
さらに、値を変更・追加・削除ができるらしい。
※値の変更・追加・削除に関しては直接オリジナルのJSONに対して行われる
 わけではないみたい

Java EE 8 の新機能概要のご紹介 | 寺田 佳央 - Yoshio Terada

苦手克服!例外スタックトレースから読み解くバグ

登壇者がTwitter4Jの作者だったのと、バグ探しが苦手なので聴いてみた。
この講演が今回一番ためになったと思う。

例外の種類

読み解くための知識としてまずは例外の種類について説明

  • ランタイム例外

 コンパイルは通るが実行時に起きる例外のこと。
 try~catchが必要ない。
 NullPointerExceptionなど

  • 例外

 コンパイルが通らない例外のこと。
 try~catchが必要。
 IOExceptionなど

例外とエラーの関係

あまり意識していなかったが例外とエラーは全くの別物だということ

  • 例外

 自分で修正が可能、リカバーができるもの。
 ファイルの入出力失敗やヌルポなど、ロジックの不備で起きる

  • エラー

 自分で修正が不可能、リカバー出来ないもの。
 実行環境のせいで正常に動作できないこと。
 メモリ、ヒープ不足やスタックが溢れるなど。

Javaのクラス階層でも例外は
java.lang.Object←java.lang.Throwable←java.lang.Exception

エラーは
java.lang.Object←java.lang.Throwable←java.lang.Error

という風に分けられている。


あとは、スレッドダンプの説明とjpsコマンドでプロセスの状態がわかるという内容だった。

Reactive Webアプリケーション – そしてSpring 5へ

Reactiveという言葉を知りたくて聴いてみた。

すごい簡単にまとめるとブロッキングは悪で、ノンブロッキングで処理を行えるようにすることかと。
そうすることでレスポンスの効率を良くするみたいな感じだったと思う。
例として入力した値が変わると他の値が連動して変わるみたいなことをイメージすればいいと言ってた。

JJUG CCC 2015 Fallの感想

やっぱりこういうイベントに参加してみないと知らない技術に触れることが出来ないんだなぁと思った。
あと、参加したことで聞いたことのない用語を知って後で調べるといういい機会にもなった。
なかなか自分から知らない用語を調べようという気にはならないが、話を聴くことで気になるから調べるきっかけづくりにちょうどいいと思った。

あと、MacBookAirが超欲しくなった。
おそらく12月中旬には手元に有るんだろうなぁ……。


 

画像貼り付けマクロ(自動でリサイズ)

前に作った画像貼り付けマクロが使いにくかったので
自動でリサイズするように改良。

Option Explicit

'リサイズの割合
Public resize As Double

'画像間のセルの行数
Public spaceRow As Integer

Sub 画像貼り付けマクロ()
    Dim CB As Variant
    Dim i As Long
    Dim lastImg As Integer
    Dim imgHeight As Double
    Dim moveCell As Integer
    
    CB = Application.ClipboardFormats
    
    If CB(1) = True Then
        MsgBox "クリップボードは空です", 48
        Exit Sub
    End If
    
    For i = 1 To UBound(CB)
        If CB(i) = xlClipboardFormatBitmap Then
        
            '画像貼り付け
            ActiveSheet.Paste
            
            '最後に貼った画像を選択
            lastImg = ActiveSheet.Shapes.Count
            ActiveSheet.Shapes(lastImg).Select
            
            'リサイズの値が0以外の時にリサイズを実行
            If 0 <> resize Then
            
                'リサイズ
                Selection.Height = Selection.Height * resize
                Selection.Width = Selection.Width
                
            End If
            
            
            '画像の高さを取得
            imgHeight = Selection.Height
            
            If 0 <> resize Then
            
                'セルの移動数を計算
                moveCell = imgHeight \ ActiveCell.RowHeight + spaceRow
            
            Else
            
                'セルの移動数を計算
                moveCell = imgHeight \ ActiveCell.RowHeight + 2
            
            End If

            'セルの移動
            ActiveCell.Offset(moveCell, 0).Activate

            Exit For
        End If
    Next i

End Sub

そして、リサイズの値と画像間のセルの行数を設定できるように改良。
リサイズは1.00が原寸大で0.50だったら元画像の半分になる。

f:id:sndstudy:20151124215628p:plain

上が1.00で下が0.50
f:id:sndstudy:20151124220703p:plain

入力フォームのソースコード

'初期設定
Private Sub UserForm_Initialize()
      'テキストボックスに初期値を設定
      Module1.resize = 1
      Module1.spaceRow = 2
      TextBox1.Value = "1.00"
      TextBox2.Value = Module1.spaceRow
      
End Sub

'OKボタン押下時の処理
Private Sub okButton_Click()
    
    Dim re As RegExp
    Dim re2 As RegExp
    
    Set re = New RegExp
    Set re2 = New RegExp
    
    re.Pattern = "^[0-9]{1,1}\.[0-9]{1,2}$"
    re2.Pattern = "^[0-9]{1,1}$"

    '両方の値が正常値の場合
    If re.Test(TextBox1.Value) = True And re2.Test(TextBox2.Value) = True Then
    
        Module1.resize = TextBox1.Value
        Module1.spaceRow = TextBox2.Value
        
        '非表示にする
        settei.Hide

    Else
        
        'リサイズが異常値の場合
        If re.Test(TextBox1.Value) = False Then
      
            MsgBox "リサイズは0.00~9.99の間で設定してください", 48
    
        End If
        
        '行数が異常値の場合
        If re2.Test(TextBox2.Value) = False Then
      
            MsgBox "行数はは0~9の間で設定してください", 48
    
        End If
    
    End If
    
  
End Sub

一応、変な値を入力するとエラーメッセージが表示される。
f:id:sndstudy:20151124220040p:plain
f:id:sndstudy:20151124220057p:plain

入力フォームを表示するソースコード

Sub 設定フォーム表示()

    settei.Show vbModeless

End Sub

正規表現グローバル変数に少々手こずった。
やはり、セミコロンを打たないのに違和感を感じる……。

参考にしたサイト
VBAで正規表現を使う (2/3):CodeZine(コードジン)
ユーザーフォームの表示、非表示 : 初心者のためのOffice講座-SupportingBlog1
標準モジュールとフォーム間のデータ受け渡し�T|Excelユーザーフォーム入門
エクセルVBAマクロ - ユーザフォーム - ラベル
ユーザーフォーム

途中に画像を挿入マクロ

画像を連続で貼り付けていて、途中で画像を貼り忘れた時に使えそうなマクロを作成。

Sub 途中に画像を挿入マクロ()
    Dim CB As Variant
    Dim i As Long
    Dim lastImg As Integer
    Dim imgHeight As Double
    Dim moveCell As Integer
    Dim cellRow As Long
    Dim insertRow As Long
    
    CB = Application.ClipboardFormats
    
    If CB(1) = True Then
        MsgBox "クリップボードは空です", 48
        Exit Sub
    End If
    
    For i = 1 To UBound(CB)
        If CB(i) = xlClipboardFormatBitmap Then
                    
            '行を1行挿入する
            Rows(ActiveCell.Row).Insert
            
            'セルの移動
            ActiveCell.Offset(1, 0).Activate
        
            '画像貼り付け
            ActiveSheet.Paste
            
            '最後に貼った画像を選択
            lastImg = ActiveSheet.Shapes.Count
            ActiveSheet.Shapes(lastImg).Select
            
            '画像の高さを取得
            imgHeight = Selection.Height
            
            '現在のセルの行を取得
            cellRow = ActiveCell.Row
            
            '挿入する行の数を計算
            insertRow = imgHeight \ ActiveCell.RowHeight
            
            '行を挿入する
            Range(cellRow + 1 & ":" & (cellRow + insertRow + 1)).Insert
            
            'セルの移動数を計算
            moveCell = insertRow + 1

            'セルの移動
            ActiveCell.Offset(moveCell, 0).Activate

            Exit For
        End If
    Next i

End Sub

画像と画像の間にセルを合わせて……。
f:id:sndstudy:20151123221117p:plain

画像間に挿入される。
f:id:sndstudy:20151123221202p:plain

画像貼り付けマクロ

キャプチャした画像をExcelに貼っていくマクロを作成した。

Sub 画像貼り付けマクロ()
    Dim CB As Variant
    Dim i As Long
    Dim lastImg As Integer
    Dim imgHeight As Double
    Dim moveCell As Integer
    
    CB = Application.ClipboardFormats
    
    If CB(1) = True Then
        MsgBox "クリップボードは空です", 48
        Exit Sub
    End If
    
    For i = 1 To UBound(CB)
        If CB(i) = xlClipboardFormatBitmap Then
        
            '画像貼り付け
            ActiveSheet.Paste
            
            '最後に貼った画像を選択
            lastImg = ActiveSheet.Shapes.Count
            ActiveSheet.Shapes(lastImg).Select
            
            '画像の高さを取得
            imgHeight = Selection.Height
            
            'セルの移動数を計算
            moveCell = imgHeight \ ActiveCell.RowHeight + 2

            'セルの移動
            ActiveCell.Offset(moveCell, 0).Activate

            Exit For
        End If
    Next i

End Sub

キャプチャした画像を1行ずつ、離しながら
貼り付けることができる。

f:id:sndstudy:20151122001257p:plain

途中で画像のサイズが変わっても大丈夫。

f:id:sndstudy:20151122001405p:plain

参考にしたサイト

Office TANAKA - Excel VBA Tips[クリップボードを操作する(1)]

クリップボード、もしくは貼り付けた画像の高さ - その他MS Office | 【OKWave】

Twitter4Jを用いて、ハッシュタグを検索するWebアプリ作ってみた

少し気になったので作ってみた。

まずは環境設定。

Twitter4J - A Java library for the Twitter API
↑公式ページからダウンロードしてくる。

Eclipseのlibフォルダにjarファイルを入れるだけで簡単だった。

TwitterAPIを使用するので、以下の4つが必要みたい。

  1. Consumer key
  2. Consumer secret
  3. Access token
  4. Access token secret

Twitter Developers
↑このサイトで取得する。

twitter4j.propertiesに取得したキーを書いて、
srcフォルダ直下にtwitter4j.propertiesを置く
Twitter4J - 設定

基本的に公式サイトの通りに書けば動くはず。


index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>トップページ</title>
<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>

	<label>検索したいハッシュタグを入力してください</label>
	<form action="./twitter" method="post">
		#<input type="text" name="searchTarget" id="tweets">
		<input type="submit" value="送信">
	</form>

</body>
</html>

f:id:sndstudy:20151109211536p:plain

例えば#ごちうさを検索したいときは……。

f:id:sndstudy:20151109211822p:plain

f:id:sndstudy:20151109211842p:plain

上記のように出力される。

サーブレット(TwitterServlet.java)

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;

/**
 * ツイッターサーブレット
 *
 */
public class TwitterServlet extends HttpServlet{

	/**
	 * post処理
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		//受信した文字列をUTF-8にエンコーディング
		req.setCharacterEncoding("UTF-8");

		//検索したいハッシュタグ
		String searchTarget = "#" + req.getParameter("searchTarget");

		//フォワード先
		String forwardPage = "./WEB-INF/jsp/twitter.jsp";

		//Twitterのインスタンス取得
        Twitter twitter = new TwitterFactory().getInstance();

        //Queryのインスタンス生成
        Query query = new Query();

        //検索ワードを設定する
        query.setQuery(searchTarget);

        //検索結果を格納する変数を設定
        QueryResult queryResult = null;

        try {
        	//検索を実行
			queryResult = twitter.search(query);
		} catch (TwitterException e1) {
			e1.printStackTrace();
		}

        //検索した結果のヒット数を標準出力(デフォルトはMAX15件)
		System.out.println("ヒット数:" + queryResult.getTweets().size());

		List<String> result = new ArrayList<String>();

		//Listに検索結果を格納する
		for(Status tweet : queryResult.getTweets()){

			result.add(tweet.getText());

		}

		req.setAttribute("result", result);

		RequestDispatcher dispatch = req.getRequestDispatcher(forwardPage);

		//フォワード
		dispatch.forward(req, resp);

	}

}

出力JSP(twitter.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%List<String> searchResult = (List<String>)request.getAttribute("result"); %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="./css/index.css">
<title>出力結果</title>
</head>
<body>

	<% for(int i = 0; i < searchResult.size(); i++){ %>
		<div class="resultOutput">
			<%=searchResult.get(i) %>
		</div>
	<%} %>

</body>
</html>

発見したこと
→同じ内容のツイートを連続投稿出来ないこと
Twitterの仕様だと思うが、多分荒らし対策とかなんだろうな。


地味に苦戦した点
→外部CSSの修正部分が反映されない

IDを変更して、実行したら何故か出力結果で四角で囲まれなかったことがあった。

【Eclipse】Eclipseで、外部JS / 外部CSS / 画像の変更が、反映させれない ( ソフトウェア ) - プログラム の個人的なメモ - Yahoo!ブログ


とりあえずサーバのクリーンで修正部分が反映された。



次は非同期通信で検索結果がどんどん更新されるように実装を行ってみたい。