Archive
.NET の動作しているプラットフォームを取得
.NET Framework が動作するプラットフォームを取得するには System.Environment.OSVersion を取得すれば良いように思います。しかし以下のコードを Mac OS X で動かすと,期待する結果を得られません。
var platform = Environment.OSVersion.Platform; Console.WriteLine(platform == PlatformID.MacOSX); // false
実は Mac OS X では platform には PlatformID.Unix になります[a]。
苦肉の策ではありますが, UNIX 系 OS に標準で搭載されている uname を用いて OS を調べることができます[b]。
var platform = Environment.OSVersion.Platform;
if (platform != PlatformID.Unix)
{
return platform;
}
using (var uname = new Process())
{
uname.StartInfo.FileName = "uname";
uname.StartInfo.Arguments = "-s";
uname.StartInfo.RedirectStandardOutput = true;
uname.StartInfo.UseShellExecute = false;
uname.Start();
var kernelName = uname.StandardOutput.ReadLine();
uname.WaitForExit();
return kernelName == "Darwin" ? PlatformID.MacOSX : PlatformID.Unix;
}
カーネルの名前が Darwin ならば Mac OS X,そうでなければその他の UNIX であるとしています。 PATH が変更されていたら例外が投げられるなどいろいろ問題がありますが,とりあえずうまくいくと思います。
脚注
- Bug 515570 - System.Environment.OSVersion.Platform returns wrong result on Mac OS X [↩]
- リンク先では
-aオプションと書いてありますが,-sオプション (オプションなしと同じ) で十分だとます。 [↩]
C# のジェネリックで Enum/Delegate 制約を使う
C# のジェネリック型制約には大きな制限があります。それは制約する型に System.Delegate や System.Enum が使えないということです。 F# や Nemerle といった,ジェネリックの制約型に制限がない別の言語を用いるという選択肢も当然考えられますが,可能な限り C# だけで解決したいということもあるかもしれません。
とは言っても C# でできないから困ってるのであって,本当に C# だけで解決するのは難しいです。そこでもう少し低レベルな MSIL を使って解決しましょう。
R の関数の引数の数を得る
args 関数を使うことで,関数の引数リストを取得することができます。
args(sqrt)
ここで得られる結果はクロージャオブジェクトなので, formals 関数により,リストオブジェクトにすることができます。
formals(args(sqrt))
リストなので, length 関数により引数の数を得ることができます[a]。
length(formals(args(sqrt)))
これを用いて,例えば,特定の名前空間に存在するすべての関数の引数の数を取得したい場合は次のようにできます。
e <- asNamespace("stats")
exports <- sapply(ls(envir=e), get, envir=e)
functions <- exports[sapply(exports, is.function)]
sapply(functions, function(f) length(formals(args(f))))
結果は stats 名前空間に公開された関数の引数の個数の名前付きベクトルです。ジェネリック関数のように重複もありますが,これで引数の個数の分布を調べても面白いと思います。
脚注
- ただし,
...は 1 つの引数として扱われます。 [↩]

最近のコメント