はじめに
Java9
からREPLツールとしてJShell
が搭載されました。
Java11
では事前のjavac
なしでJavaファイルの実行が出来るようになりました。
あとpaiza.IOとかのオンライン実行環境も便利ですね。
確実に手軽に実行できるようにはなってはいます。
ただ、もっと簡単にプログラム試せないかしら・・・。
せやクリップボードに張り付いているJavaコード実行できたらいいんじゃないかしら・・・
ということで、表題のクリップボードに保存されているJavaコードを実行するを思いつきました。
軽くインターネット調べてみたものの、自分で調べた限りは出てこなかったので作ってみます。
(そもそも必要ないから出てこないんじゃ・・・もはや何か臭う・・というのは置いといて。)
つくってみた
仕掛けとしては、クリップボードから文字列取得し、その文字列を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で書きました。
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
に引き渡す役割ですね。
@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
続行するには何かキーを押してください . . .
あらいい感じ
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日
続行するには何かキーを押してください . . .
でけたぁ
おわりに
・インターネットからコピってきたプログラム(完成しているプログラム)を実行するのには使えそう。
・いちいち標準出力(System.out~)しないといけないのが面倒くさい。
・間違えてJavaコード以外をコピーして実行しがち。どえらい怒られる
・行コメントが途中に入ったら、後続がコメントと見なされてロジックが全く評価されない。(ここは改善の余地ありそう?)
・やはりゴミツール・・な気もするけど、やはり我が子はかわいい
・それセキュリティ大丈夫なんか。byインフラエンジニア
・反省はしていない。
以上、メリークリスマスでございます