クリップボードに保存されているJavaコードを実行する。

# はじめに
ちょっとしたJavaプログラムを試したいことありますよね？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/315651/ea36e07b-a43e-8a3c-ffbd-09f0640ed17f.png)


`Java9`からREPLツールとして`JShell`が搭載されました。
`Java11`では事前の`javac`なしでJavaファイルの実行が出来るようになりました。
あと[paiza.IO](https://paiza.io/ja)とかのオンライン実行環境も便利ですね。

確実に手軽に実行できるようにはなってはいます。
ただ、もっと簡単にプログラム試せないかしら・・・。
せや:bangbang:クリップボードに張り付いているJavaコード実行できたらいいんじゃないかしら・・・:point_up:

ということで、表題の<font color='blue'><b>クリップボードに保存されているJavaコードを実行する</b></font>を思いつきました。

軽くインターネット調べてみたものの、自分で調べた限りは出てこなかったので作ってみます。
（そもそも必要ないから出てこないんじゃ・・・:poop:もはや何か臭う・・:poop:というのは置いといて。）

# つくってみた
仕掛けとしては、クリップボードから文字列取得し、その文字列を`jshell`に引き渡すという単純な仕掛けですね。
ちなみに`JShell`にはデフォルトで以下のパッケージがimportされています。

```
jshell> /import
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*
```



まずはクリップボードから文字列取得する部分を作ります。
別になんでも良いのですが、Javaで書きました。

``` PrintClipboardString.java
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
/**
 * クリップボードから文字列データを出力します。
 */
public class PrintClipboardString {
    /**
     * メイン
     */
    public static void main(String[] args) {
        System.out.println(getClipboardString());
    }
    /**
     * クリップボードから文字列データを返します。
     * 
     * @return クリップボードの文字列データを返します。文字列データでない場合はnullを返します。
     */
    public static String getClipboardString() {
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();

        try {
            return (String) clip.getData(DataFlavor.stringFlavor);
        } catch (UnsupportedFlavorException e) {
            return null;
        } catch (IOException e) {
            return null;
        }
    }
}

```

次はこの`PrintClipboardString.java`を利用するバッチファイル(DOS)作ります。
クリップボードから文字列データを取得して、`JShell`に引き渡す役割ですね。

``` clipbord_jshell.bat
@echo off
setlocal enabledelayedexpansion

set CLIP_BOARD=
for /f "usebackq tokens=*" %%i in (`java PrintClipboardString`) do (
    set CLIP_BOARD=!CLIP_BOARD!^
%%i
)
echo =============
echo  ソース
echo =============
echo !CLIP_BOARD!
echo.

echo =============
echo  実行結果
echo =============
echo !CLIP_BOARD! | jshell -
echo.

pause
```

これ`DOS`なのでコマンド実行結果を扱う部分の考慮でfor文使っていますが、`Unix系シェル`だと普通にバッククォート使えるので簡単だと思います。

# つかってみた
#### 1.文字列出力してみた。
`System.out.println("hello");`
↑このテキストをコピー(クリップボードに格納)して、バッチファイル実行します。

```
$clipbord_jshell.bat
=============
 ソース
=============
System.out.println("hello");

=============
 実行結果
=============
hello

続行するには何かキーを押してください . . .
```

あらいい感じ:sunny:

#### 2.Mathクラス使ってみた。
`System.out.println(Math.random());`
`System.out.println(Math.random());`
`System.out.println(Math.random());`

↑このテキスト3行をコピー(クリップボードに格納)して、バッチファイル実行します。

```
$clipbord_jshell.bat
=============
 ソース
=============
System.out.println(Math.random());System.out.println(Math.random());System.out.println(Math.random());

=============
 実行結果
=============
0.13619188697681628
0.6036857063092008
0.7567411771330568

続行するには何かキーを押してください . . .
```
ソースが1行表示されてしまいましたが・・・、複数行でも実行結果はいい感じですね。
`JShell`で`java.math.*`がimport済みなので、別途importせずとも実行できました。

#### 3.クリスマスまであと何日か数えてみた。
日付操作系って比較的試したいケースが多いと思うんですよね。

`import java.time.LocalDateTime;`
`import java.time.temporal.ChronoUnit;`
`LocalDateTime d = LocalDateTime.now();`
`LocalDateTime c = LocalDateTime.of(2018, 12, 25 , 23, 59);`
`System.out.println("クリスマスまであと・・・" + ChronoUnit.DAYS.between(d, c) + "日");`
↑このテキスト5行をコピー(クリップボードに格納)して、バッチファイル実行します。

```
$clipbord_jshell.bat
=============
 ソース
=============
import java.time.LocalDateTime;import java.time.temporal.ChronoUnit;LocalDateTime d = LocalDateTime.now();LocalDateTime c = LocalDateTime.of(2018, 12,
 25 , 23, 59);System.out.println("クリスマスまであと・・・" + ChronoUnit.DAYS.between(d, c) + "日");

=============
 実行結果
=============
クリスマスまであと・・・20日

続行するには何かキーを押してください . . .
```

でけたぁ:relaxed:

# おわりに
・インターネットからコピってきたプログラム(完成しているプログラム)を実行するのには使えそう。
・いちいち標準出力(System.out～)しないといけないのが面倒くさい。
・間違えてJavaコード以外をコピーして実行しがち。どえらい怒られる:no_good_tone3:
・行コメントが途中に入ったら、後続がコメントと見なされてロジックが全く評価されない。（ここは改善の余地ありそう？）
・やはりゴミツール・・な気もするけど、やはり我が子はかわいい:poop:
・それセキュリティ大丈夫なんか。ｂｙインフラエンジニア
・反省はしていない。

以上、メリークリスマスでございます:christmas_tree: