htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

全てのフレームを対象にするには

某大手工業系企業の新規開発プロジェクトに参画しているのですが、非常に悲しいことに社内ポータルが未だにフレームを使用したサイトなのです。
フレームを使うと容易にペインで分けたサイトを構築できるため、実用重視のエンタープライズ界隈で重宝されるのはよく分かります。

ただ、フレーム*1を使うと、ブックマークレットを作ろうと思ったときにそのままではトップレベルのウィンドウにしか効力を発揮しません。
埋め込まれているフレームのソースURLがトップレベルのウィンドウと同じドメインに属しているのであれば*2、以下のようなコードを使うことで全フレームに対して操作することができます。

// for IE9+
(function loop(win) {
  return Array.prototype.reduce.call(win, function(p, c) {
    return p.concat(loop(c.window));
  }, [win]);
})(window)
.forEach(function(window) {
  var document;
  try { document = window.document; } catch(e) { return; }
  /* code here */
});
// compressed
(function l(w){return [].reduce.call(w,function(p,c){return p.concat(l(c.window))},[w])})(window).forEach(function(w){try{var d=w.document}catch(e){return}/* code here */})

*1:<iframe>も同様です。

*2:Same-Origin PolicyはWebにおける重要な概念です。

最近 Nemerle がマイブームです

私自身は最近知ったのですが、実は以前からある言語っぽいですね。
C#によく似た構文を数多く持ち、関数型言語によく見られる機能(パターンマッチングとかタプルとか)を言語レベルで実装しているのが特徴です。
型を静的にチェックできる強力なマクロもあって、かなり自由度の高いコードが書けるようです。
foreach文なんかもマクロで書かれているそうです。

あと#pragma indentディレクティブを宣言することでPythonやF#, CoffeeScript, Haml, SASSなどで馴染みのある「インデントが意味を持つ」書き方ができます。

自分はまだそこまで使いこなせてないですが、書いていてすごく楽しいです。
知名度もそれほどなくコミュニティもあまり活発ではないようですが、C#もF#も好きって人には向いているんではないでしょうか。

例えば、以下は拙い知識で書いたフィボナッチ数列を求めるコードです。 gist.github.com

これはC#で書くと大体こんなような感じです。

using static System.Console;
using System.Numerics;

static class Program
{
    static void Main()
    {
        Action<int> fib = null;
        fib = n =>
        {
            WriteLine("{0,8} : {1}", n, Fibonacci(n));
            if (n % 10 == 0) ReadLine();
            fib(n + 1);
        };

        fib(1);
    }

    private static BigInteger Fibonacci(int n)
    {
        var a = BigInteger.Zero;
        var b = BigInteger.One;

        foreach (int i in Enumerable.Range(0, 31).Reverse())
        {
            BigInteger c = a;
            a = a * (b * 2 - a);
            b = c * c + b * b;

            if ((((uint)n >> i) & 1) != 0)
            {
                c = a;
                a = b;
                b = c + b;
            }
        }
        return a;
    }
}

これだけだと正直何がいいのか伝わらない自覚はあります。
Nemerleらしい箇所はタプルでの多重代入とdefを使った型推論くらい…。

match (expr)defの直下やforeachの直下で省略できるため、

// A(文字コード: 65)からz(同: 122)までの大文字で、かつ偶数番目に出現する文字のみを出力
foreach (c in $['A' .. 'z'] with index)
{
  | x when char.IsUpper(x) && index % 2 == 1 => Write(c)
  | _ => ()
}
WriteLine();

// 冗長に書くとこう
foreach (c in $['A' .. 'z'] with index)
{
  match (c)
  {
    | x when char.IsUpper(x) && index % 2 == 1 => Write(c)
    | _ => ()
  }
}

こんな感じでforeachからのパターンマッチとかやるとちょっとはメリットが見えてくるかもしれません。
分かりやすさのためにあえてcxと変数名を変えましたが、Nemerleはスコープが異なる場合は変数名のオーバーライドが可能なので、

// 上のコードで、4行目をこう書いても意味は同じ
  | c when char.IsUpper(c) && index % 2 == 1 => Write(c)

です。

こんなコードも書けます。

Main() : void
{
  def n = 10;
  
  def somefunc(n)
  {
    $[n ** 3, n in [1 .. n]]
  }
  
  def listToString(list)
  {
    "[" + string.Join(", ", list) + "]"
  }
  
  def list = somefunc(n);
  WriteLine(listToString(list));
}

nが何を指しているのか、コンテキストが分かりづらいのでほどほどにするのがよさげですね。

個人的には自由度が上がったC#の延長、みたいな感じに捉えています。
地味にC# 7.0から対応の2進数リテラル0b1011みたいなの)もとっくのとうに実装済みだったり、便利です。

そんなわけで、はてなさんにはNemerleシンタックスハイライトに対応していただきたく。

リンク化スクリプト

かねてからHatena::Let で公開 *1 していて、個人的にもかなり使っているスクリプトGreaseMonkey用に書き直したのでそれも公開してみます。
https://gist.github.com/htsign/5eed5473a9e75c7c45f3a5571d7d0803/raw/convertTextToLink.user.js

GreaseMonkey用っていうか単にES2015で書き直しただけで、特別GreaseMonkeyには依存していませんが。

せっかくなのでGreaseMonkey版はMutationObserverによる追加ノードの監視機能も付けました。
Hatena::Letの方(以下、ブックマークレット版)にはこの機能は持たせていません。
対象となるブラウザの範囲にIEも入るからです。
新しいノードに適用する為には都度実行してやれば済む話で、別にそんなに手間なわけでもありませんし。

一応Mutation Eventsdocument.addEventListener("DOMNodeInserted", ...みたいなやつ)はIE9から対応していますが、これは既に非推奨となった技術なので積極的に採用するつもりはないです。
場合分けめんどいですしね(本音)

NodeIteratorで探索しているのでそれなりに速いと思いますが、そもそもの計算量の時点でたかが知れてるのでアレです。

注意点として、テキストに対して要素を追加する(DOMに破壊的変更を加える)為、DOMの構造に依存した外部コードがある場合には不具合の原因となる可能性があります。

*1:ブックマークレット版もES2015版での大幅な編集に合わせてだいぶ構造変わってます

他の人がエントリに書いてた仕分けbatが冗長だったのでvbsにした

www.ken10blog.com

本当はC#とかでパパッと書いてしまうのが楽だけど、元ネタがバッチファイルなのでWindows標準で動くスクリプトという点でWSHを選びました。*1
PowerShellはローカルで気軽に動かすためにポリシーを変更する必要があるので却下。

Option Explicit

Const ForWriting = 2
Const TristateFalse = 0

Dim wsh, fso
Set wsh = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
wsh.CurrentDirectory = fso.GetParentFolderName(WScript.ScriptFullName)

Dim logfile, folder, file
Set logfile = fso.OpenTextFile("imageFiltering.log", ForWriting, True, TristateFalse)
Set folder  = fso.GetFolder(wsh.CurrentDirectory)

For Each file In folder.Files
    Dim name, index
    name = file.Name
    index = InStrRev(name, ".")
    
    If index > 0 Then
        Dim ext
        ext = Mid(name, index + 1)
        
        Select Case LCase(ext)
            Case "jpg", "jpeg", "gif", "png"
                Call Move(name)
        End Select
    End If
Next

Function Move(filename)
    Dim re, ms, m
    Set re = New RegExp
    re.Pattern = "モデル\:([^]]+)"
    
    Set ms = re.Execute(filename)
    For Each m In ms
        Dim matched, models, model
        matched = m.SubMatches(0)
        models = Split(matched)
        
        For Each model In models
            If Not fso.FolderExists(model) Then
                fso.CreateFolder model
            End If
            
            logfile.WriteLine "【" & filename & "】を【" & model & "】フォルダにコピー"
            fso.CopyFile filename, fso.BuildPath(model, filename)
        Next
        
        logfile.WriteLine "【" & filename & "】を削除"
        fso.DeleteFile filename
    Next
    
    Set ms = Nothing
    Set re = Nothing
End Function


logfile.Close
Set logfile = Nothing
Set folder  = Nothing
Set fso     = Nothing
Set wsh     = Nothing

スクリプトShift-JISで保存しないと正規表現エンジンが正しく動作しません。
あと例外処理とかなにもしてないのでその辺はよしなに。

書いてる途中でいっそファイルのダウンロードも自動化しようかとも思ったけどめんどくさいのでやめました。

*1:実はC#コンパイラであるcsc.exeはWindowsシステムフォルダの奥深くに初めから入っていますが、それはまた別のお話。

個人的によく使うWindowsコマンドまとめ

Twitterで戯れていたら流れで思いついたので唐突にまとめてみます。
「個人的によく使う」というのがミソで、ここに載っていないものは載せ忘れかほとんど使わないか存在を知らないものです。
載せ忘れは思い出し次第追記していきます。

基本

Win+Rで「ファイル名を指定して実行」を呼び出せます。
Win+Rで起動したプログラムは通常ユーザー権限で起動する為、明示的に管理者権限で起動させたい場合は「Winを一回だけ押し(スタートメニュー呼び出し)てコマンド打ってCtrl+Shift+Enter」です。

ただし、スタートメニューを使う方法はコマンド履歴が残らないので、毎回全部打ち込む必要があってちょっと面倒くさいです。
可能な限りWin+Rを使う方法をお勧めします。

なお、コマンドは大文字小文字を区別しません。
ここでは分かりやすさの為に一部大文字で表記しますが、普段は全て小文字で打っています。

リスト

基本系

  • cmd
    • 言わずと知れたコマンドプロンプト
      • 上記の「管理者権限で起動」で起動することが最も多いコマンド
  • .
    • エクスプローラ
      • 一文字だけで起動できるので便利と言えば便利。普段はWin+E使うことの方が多いです。
  • \
    • エクスプローラ
      • こちらはシステムドライブ(厳密にはユーザーデータが保管されているカレントドライブのルート)が表示されます。

ツール系

  • notepad
    • メモ帳
      • ささっと何かメモっておきたいときに
  • write
    • ワードパッド
      • ちょっと豪華なメモ帳かつちょっと簡素なMS Wordみたいな立ち位置。名前の通りwordpadでも起動します。
  • calc
    • 電卓
  • mspaint
    • ペイント
      • 旧名の「ペイントブラシ」から来ているpbrushでも等価です。
  • mstsc
  • winword
    • MS Word
      • 当然ながら MS Office インストール前提です。
  • excel
  • powerpnt
  • powershell_ise
  • psr
    • ステップ記録ツール
      • 「Probrem Steps Recorder」の略です。
        あらゆる操作手順を画像つきで記録してくれるスグレモノですが、名前の通り本来は問題が起こったときの報告用ツールなので、記録データには一部デバッグ情報も含まれます。あと、画像は強力に圧縮されたJPEGで結構汚いです。

コントロールパネル系

  • sysdm.cpl
    • システムのプロパティ
      • 何かとお世話になることがあると思います。
  • SystemPropertiesAdvanced
    • 「システムのプロパティ」の「詳細設定」タブ
      • なぜこれ単体でexeファイルが用意されているのか謎。
        もっと言うと全てのタブ(と一部の機能)ごとにそのタブや機能を直接呼べるexeファイルがあります。
        f:id:htsign:20161213212521p:plain
  • ncpa.cpl
  • inetcpl.cpl
    • インターネットのプロパティ
      • IE使わない人にとってはプロクシの設定くらいでしかお世話にならない。
  • main.cpl
    • マウスのプロパティ
      • 何を略して main になったのか分かりません。
  • mmsys.cpl
    • サウンド
  • fonts
    • フォント
  • firewall.cpl
  • wf.msc
  • powercfg.cpl
    • 電源オプション
      • ちなみに拡張子を省略すると同名のpowercfg.exeが呼び出されます。一瞬黒い画面が表示されてすぐ消えます。
  • control folders
    • フォルダオプション
  • control userpasswords2
    • ユーザーアカウント
      • ちなみにcontrol userpasswordsだと、コントロールパネルから呼べるユーザーアカウントと等価です。
  • appwiz.cpl
    • プログラムと機能
  • OptionalFeatures
    • Windows の機能の有効化または無効化
  • wuapp
  • control /name Microsoft.WindowsUpdate
    • Windows Update
      • こちらはWindows 10でも使えます。が、wuappと比較して圧倒的に記述量が多く、打つのがダルいです。2回目以降は履歴が残るので楽に指定できます。
  • control /name Microsoft.DefaultPrograms
    • 既定のプログラム
      • 余談ですが、control /nameによる呼び出しはたくさんあり、例えばcontrol /name Microsoft.AudioDevicesAndSoundThemesmmsys.cplと同等です。
        Microsoftは長ったらしい呼び出しの方を推奨しています。今後置き換えを図っていくものと思います。
  • control /name Microsoft.System
    • システム
      • Win+Pauseでも同じ効果なので、Pauseキーがあるキーボードを使える場合はショートカットキーを使っています。
  • taskschd.msc
    • タスクスケジューラ
      • タスクスケジューラを上手く活用するとUACのバイパスとかできるようになりますが、セキュリティリスクの増大にもつながるので、計画的に使いましょう。
  • devmgmt.msc
    • バイスマネージャ
      • mgmt.msc」シリーズ筆頭
        おそらく「DEVice ManaGeMenT」の略でしょう。
  • diskmgmt.msc
    • ディスクの管理
  • compmgmt.msc
    • コンピュータの管理
      • これ一つでいろいろ入ってるので、これを覚えればtaskschd.msc devmgmt.msc diskmgmt.msc services.msc fsmgmt.msc等を覚えなくていいと考えることもできます。
        でもdevmgmt.mscservices.mscは特によく使うので、個人的には習得必須ですね。
  • services.msc
    • サービス
  • fsmgmt.msc
    • 共有フォルダ
  • certmgr.msc
    • 証明書のアレやコレ

shellスキーム系

  • shell:sendto
    • コンテキストメニューの「送る」フォルダの実体
      • ここにショートカットファイルを置いて「送る」の項目を増やしたり、ショートカットを削除して(or 隠し属性付けて)項目を減らしたりできます。
  • shell:programs
    • プログラムメニューの実体
  • shell:startup
    • プログラムメニューの中でも特に「スタートアップ」フォルダ
      • 気軽に使えるので便利ですが、しっかりセットアップするときはレジストリHKCU\Software\Microsoft\Windows\CurrentVersion\Runに置く方が好きです。
  • shell:recent
    • 最近使ったファイル
  • shell:desktop
    • デスクトップ
      • 使う場面はそう無いと思います。
  • shell:appdata
    • AppDataのRoaming
      • 入力速度的には%appdata%といい勝負

システム系

  • msinfo32
    • システム情報
  • dxdiag
    • DirectX 診断ツール
      • 個人的にはこいつ呼ばなくてもmsinfo32で済む場面が多いです。
  • cleanmgr
    • ディスクのクリーンアップ
  • perfmon
    • パフォーマンスモニタ
  • eventvwr
    • イベントビューア
  • regedit
  • taskmgr
    • タスクマネージャ
      • でもCtrl+Shift+Escで起動することの方が圧倒的に多いです。
        タブレット機ではタスクバー右クリックが多いです。
  • shutdown -s -t 0
    • OSの終了
  • shutdown -r -t 0
    • OSの再起動
      • これを覚えておくだけで、例えば不意にグラフィクスドライバのみがクラッシュして復帰しなくなった(音楽等は正常に鳴っていたりするのに画面描画だけ何やっても更新されない)場合にも、電源長押しせずに、慌てずこれ打ち込んで再起動させることができるようになります。

マニアック系

  • wbemtest
    • WMIテストツール
      • WBEM」は「うぇぶえむ」と読みます。WBEMという規格のMicrosoft実装がWMIです。
        WQLのコールとかできます。

最後に

コマンドは自然に指が動くくらいでないとマウスでぽちぽちするより逆に遅くなるので、便利に使いたいと思ったらきっかり覚えましょう。