約 3,226,599 件
https://w.atwiki.jp/ktakeda/pages/11.html
インスタグラムプラグイン 人気の画像共有サービス、Instagram(インスタグラム)の画像をアットウィキに貼れるプラグインです。 #ig_user(ユーザー名) と記載することで、特定ユーザーのInstagramのフィードを表示することができます。 例)@dogoftheday #ig_user #ig_tags(タグ名) と記載することで、特定タグのInstagramのフィードを表示することができます。 #dogofthedayjp タグ #ig_tag #ig_popular と記載することで、Instagramのpopularフィードを表示することができます。 詳しい使い方は以下のページを参考にしてください! =>http //www1.atwiki.jp/guide/pages/935.html
https://w.atwiki.jp/gen3/pages/28.html
TiltTest.c Windowsプログラミングにはなじみが無いので、関数がどこから来たものか調べながら読み下してみる。 #include windows.h // ... Microsoft SDKs/Windows/v7.0/include/windows.h #include math.h // ... Microsoft Visual Studio 10.0/VC/include/math.h #include string.h // ... 上に同じ #include "wintab.h" // NOTE get from wactab header package (TiltTest.zipに同梱) #define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | \ PK_ORIENTATION | PK_CURSOR) // PK_xxはwintab.h内で定義 #define PACKETMODE 0 #include "pktdef.h" // NOTE get from wactab header package (TiltTest.zipに同梱) #include "msgpack.h" // (TiltTest.zipに同梱) #include "Utils.h" // (TiltTest.zipに同梱) #include "tilttest.h" // (TiltTest.zipに同梱) /* converts FIX32 to double */ #define FIX_DOUBLE(x) ((double)(INT(x))+((double)FRAC(x)/65536)) #define pi 3.14159265359 ここまでは特に難しいことはない。 #ifdef WIN32 #define MoveTo(h,x,y) MoveToEx(h,x,y,NULL) #endif MoveToEx は Microsoft SDKs/Windows/v7.0A/Include/WinGDI.h の4520行にプロトタイプ宣言?がある。 char*gpszProgramName = "TiltTest"; HANDLE hInst; /* Handle for instance */ HCTX hTab = NULL; /* Handle for Tablet Context */ POINT ptNew; /* XY value storage */ UINT prsNew; /* Pressure value storage */ UINT curNew; /* Cursor number storage */ ORIENTATION ortNew; /* Tilt value storage */ RECT rcClient; /* Size of current Client */ RECT rcInfoTilt; /* Size of tilt info box */ RECT rcInfoName; /* Size of cursor name box */ RECT rcInfoGen; /* Size of testing box */ RECT rcDraw; /* Size of draw area */ double aziFactor = 1; /* Azimuth factor */ double altFactor = 1; /* Altitude factor */ double altAdjust = 1; /* Altitude zero adjust */ BOOL tilt_support = TRUE; /* Is tilt supported */ 以上はグローバル変数の定義。 ptNew以後は、タブレットから来たデータを保持する構造体を指すポインタらしい。 上から順に、XY座標、筆圧、カーソル番号(ペン先か消しゴムかひょっとするとサイドスイッチの状態も)、ペンの傾き角度、の様子。 rcClient以後は、情報をウインドウ上に表示するエリアのための構造体らしい。 aziFactor ... 方位角についての何らかの係数 altFactor ... 加速度についての何らかの係数 altAdjust ... 加速度についての何らかの係数 最後に、ペンの傾きをサポートしてないタブレットではflaseになるBOOL型変数か。 ここでカーソル番号curNewの内容として、ペンのペン先か消しゴム側かの情報に加えて、サイドスイッチの情報や、モノによってはタブレットに仕込まれたスイッチの情報を返しているかもしれないことに注意しておく。 また、タブレットが複数接続されている場合には hInst や hTab の内容が変わっているかもしれない。 続いてプログラム本体部分が来る。 int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) HINSTANCE hInstance; HINSTANCE hPrevInstance; LPSTR lpCmdLine; int nCmdShow; この構文だとVC++2010のデフォルトでは、インテリセンス機能による警告が出る。警告の出ない構文に書き直すと、例えば次のようになる。 int PASCAL WinMain( HINSTANCEhInstance, HINSTANCEhPrevInstance, LPSTRlpCmdLine, intnCmdShow) WinMain()の中身はいたってシンプル。 { MSG msg; if (!hPrevInstance) if (!InitApplication(hInstance)) return (FALSE); /* Perform initializations that apply to a specific instance */ if (!InitInstance(hInstance, nCmdShow)) return (FALSE); /* Acquire and dispatch messages until a WM_QUIT message is received. */ while (GetMessage( msg, NULL, 0, 0)) { TranslateMessage( msg); DispatchMessage( msg); } // Return Wintab resources. Cleanup(); return (msg.wParam); } WinMain() は Windows でのウインドウアプリケーションの主要関数で、C言語の main() に相当するものとのこと。Web を調べると、どのサンプルコードでもこの部分はほとんど違いがない。この関数が実行されたら、あとはマウスやキーボードや、TiltTest の場合はタブレットのイベント割り込みを待つことになる。 その割り込み処理をフックして、アプリケーションのコードを記述することになる。 InitApplication() BOOL InitApplication(HINSTANCE hInstance) // BOOL InitApplication(hInstance) // HANDLE hInstance; // 呼び出し側が HINSTANCE でありこの文おそらく間違いなので変更する。TILTTEST.Hも。 { WNDCLASS wc; /* Fill in window class structure with parameters that describe the */ /* main window. */ wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); wc.lpszMenuName = "TiltTestMenu"; wc.lpszClassName = "TiltTestWClass"; /* Register the window class and return success/failure code. */ return (RegisterClass( wc)); } WNDCLASS は Microsoft SDKs/Windows/v7.0A/Include/WinUser.h で 構造体 tagWNDCLASSA で定義されている。アプリケーションウインドウの雛形が作成されているのかな。 InitInstance() 長いので調査結果や変更点はソースコードにコメントの形で埋め込んだ。 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) // 第一引数の型は呼び出し側が HINSTANCE なのでそれにあわせた。TILTTEST.H も書き直した。 // HANDLE hInstance; // int nCmdShow; { HWND hWnd; /* Handle for window */ HDC hDC; /* Handle for Device Context */ TEXTMETRIC textmetric; /* Structure for font info */ int nLineH; /* Holds the text height */ int Xinch, Yinch; /* Holds the number of pixels per inch */ int Hres, Vres; /* Holds the screen resolution */ char WName[50]; /* String to hold window name */ struct tagAXIS TpOri[3]; /* The capabilities of tilt */ double tpvar; /* A temp for converting fix to double */ /* Save the instance handle in static variable, which will be used in */ /* many subsequence calls from this application to Windows. */ hInst = hInstance; hInst はこのソースのはじめで定義したグローバル変数。 if ( !LoadWintab( ) ) { ShowError( "Wintab not available" ); return FALSE; } LoadWintab()の戻り値でタブレットサービスの有無がわかるようだ。 /* check if WinTab available. */ if (!gpWTInfoA(0, 0, NULL)) { MessageBox(NULL, "WinTab Services Not Available.", gpszProgramName, MB_OK | MB_ICONHAND); return FALSE; } gpWTInfoA()の引数でタブレットに関するいろいろな情報が得られる模様。 http //www.wacomeng.com/windows/docs/Wintab_v140.htm の WTInfo を参照すると、引数は カテゴリー 情報のカテゴリ(種類)を整数で指定 インデックス カテゴリ内のどの情報かを整数で指定 戻り値を入れるバッファへのポインタ となっている。(0,0,NULL)の指定だと、必要なバッファサイズ(一番大きな情報を返すカテゴリのために必要なバッファのサイズ)を返す。 タブレットが接続されていないなど利用できない状態の場合は0を返す。上記のコードは0かどうかを見ている。 /* check if WACOM available. */ gpWTInfoA(WTI_DEVICES, DVC_NAME, WName); if (strncmp(WName,"WACOM",5)) { MessageBox(NULL, "Wacom Tablet Not Installed.", gpszProgramName, MB_OK | MB_ICONHAND); // return FALSE; } 上記のコードは、ワコム社のタブレットが接続されているかどうかを、帰ってきた値の中にWACOMの文字列があるかどうかでチェックしている。 WTI_DEVICES と DVC_NAME は .h の中で定義されているのだろう。この組み合わせでデバイスの名前を返す模様。 組み合わせる値と返る情報の表の翻訳版があったのでありがたく参照させていただく(外部参照)。 /* get info about tilt */ tilt_support = gpWTInfoA(WTI_DEVICES,DVC_ORIENTATION, TpOri); if (tilt_support) { /* does the tablet support azimuth and altitude */ if (TpOri[0].axResolution TpOri[1].axResolution) { /* convert azimuth resulution to double */ tpvar = FIX_DOUBLE(TpOri[0].axResolution); /* convert from resolution to radians */ aziFactor = tpvar/(2*pi); /* convert altitude resolution to double */ tpvar = FIX_DOUBLE(TpOri[1].axResolution); /* scale to arbitrary value to get decent line length */ altFactor = tpvar/1000; /* adjust for maximum value at vertical */ altAdjust = (double)TpOri[1].axMax/altFactor; } else { /* no so dont do tilt stuff */ tilt_support = FALSE; } } 上記はペンの傾き情報が利用できるかどうかをチェックしている模様。 /* Create a main window for this application instance. */ wsprintf(WName, "TiltTest %x", hInst); hWnd = CreateWindow( "TiltTestWClass", WName, WS_OVERLAPPEDWINDOW, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); /* If window could not be created, return "failure" */ if (!hWnd) return (FALSE); 上記はアプリケーションウインドウを表示する部分らしい。 /* Get Device Context and setup a rects to write packet info */ hDC = GetDC(hWnd); if (!hDC) return FALSE; // 以下のブロックは // ウインドウにテキストを書くための、フォントのサイズなどのパラメータを取得している。 GetTextMetrics(hDC, textmetric); nLineH = textmetric.tmExternalLeading + textmetric.tmHeight; Xinch = GetDeviceCaps(hDC, LOGPIXELSX); Yinch = GetDeviceCaps(hDC, LOGPIXELSY); Hres = GetDeviceCaps(hDC, HORZRES); Vres = GetDeviceCaps(hDC, VERTRES); ReleaseDC(hWnd, hDC); GetClientRect(hWnd, rcClient); rcInfoTilt = rcClient; rcInfoTilt.left = Xinch / 8; rcInfoTilt.top = Yinch / 8; rcInfoTilt.bottom = rcInfoTilt.top + nLineH; rcInfoName = rcInfoTilt; rcInfoName.top += nLineH; rcInfoName.bottom += nLineH; rcInfoGen = rcInfoName; rcInfoGen.top += nLineH; rcInfoGen.bottom += nLineH; rcDraw = rcInfoGen; rcDraw.left = 0; rcDraw.top += nLineH; rcDraw.bottom = rcClient.bottom; 以下、書きかけ。 /* Make the window visible; update its client area; and return "success" */ ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return (TRUE); } これを実行するとウインドウが表示され、ペンのタブレット上の位置が十字カーソルで表示され、十字カーソルを中心にして筆圧に従った大きさの円が描画される。カーソルの座標はタブレット面の座標に対応しており、タブレットドライバによるマルチモニタの割付などは無視している。 またウインドウがアクティブの間、マウスカーソルとタブレットの十字カーソルは別物として動作する。つまりマウスカーソルはマウスで、十字カーソルはタブレットペンで動く。 さらにタブ1=画面1、タブ2=画面2と割り付けてあったとき、ウインドウをどちらの画面に表示させてもタブ面の絶対座標が画面上の絶対座標に対応するかのように十字カーソルは動く。
https://w.atwiki.jp/nikukyupunipuni/pages/6.html
アーカイブ @wikiのwikiモードでは #archive_log() と入力することで、特定のウェブページを保存しておくことができます。 詳しくはこちらをご覧ください。 =>http //atwiki.jp/guide/25_171_ja.html たとえば、#archive_log()と入力すると以下のように表示されます。 保存したいURLとサイト名を入力して"アーカイブログ"をクリックしてみよう サイト名 URL
https://w.atwiki.jp/kiake77/pages/1.html
@wikiへようこそ ウィキはみんなで気軽にホームページ編集できるツールです。 このページは自由に編集することができます。 メールで送られてきたパスワードを用いてログインすることで、各種変更(サイト名、トップページ、メンバー管理、サイドページ、デザイン、ページ管理、等)することができます まずはこちらをご覧ください。 @wikiの基本操作 用途別のオススメ機能紹介 @wikiの設定/管理 おすすめ機能 気になるニュースをチェック 関連するブログ一覧を表示 その他にもいろいろな機能満載!! @wikiプラグイン @wiki便利ツール @wiki構文 バグ・不具合を見つけたら? お手数ですが、こちらからご連絡宜しくお願いいたします。 ⇒http //atwiki.jp/guide/contact.html 分からないことは? @wiki ご利用ガイド よくある質問 @wikiへお問い合わせ 等をご活用ください
https://w.atwiki.jp/tmiya/pages/127.html
Scala ひと巡り ジェネリッククラス (Generic Classes) 原ページ Java 5 (aka.JDK 1.5 [58])と同じように、Scala は、型がパラメータ化されたクラスを組み込でサポートしています。そのようなジェネリッククラスは、コレクションクラスの開発に特に役立ちます。 次はこのことを示す例です class Stack[T] { var elems List[T] = Nil def push(x T) { elems = x elems } def top T = elems.head def pop() { elems = elems.tail } } クラス Stack は、任意の要素型 T の命令型(ミュータブル 更新可能な)スタックをモデル化します。型パラメータの使用により、正しい要素(つまり型が T のもの)だけがスタック上に push されるようにできます。同様に、型パラメータを用いてメソッド top が、与えられた型の要素だけを出力することを表現できます。 次は使用方法を示すいくつかの例です object GenericsTest extends Application { val stack = new Stack[Int] stack.push(1) stack.push( a ) println(stack.top) stack.pop() println(stack.top) } 次は、このプログラムの出力です。 97 1 ジェネリック型のサブ型付けは、非変であることに注意してください。これは、もし型 Stack[Char] の文字スタックがあっても、それを型 Stack[Int] の整数スタックとしては使えないことを意味します。それでは、本当の整数を文字スタックに入れることがでてしまうので、不健全でしょう。結論を言えば、ただ S = T の場合に限り、Stack[T] は Stack[S] のサブ型になります。これは非常に制約が厳しいので、Scala は、ジェネリック型のサブ型付けの振る舞いをコントロールする、型パラメータのアノテーション機構 [17]を提供しています。 Scala ひと巡り 暗黙のパラメータ (Implicit Parameters) 原ページ 暗黙のパラメータをもつメソッドは、通常のメソッドとまったく同じように引数に適用されます。この場合、implicit ラベルは効果を持ちません。しかし、もしメソッドにその暗黙のパラメータに対する引数が書かれていないなら、そのような引数は自動的に供給されます。 暗黙のパラメータに渡すに適した実際の引数は、2 つのカテゴリに分けられます。 1 つめは、メソッド呼び出しの時点でアクセスできる、前置子のつかない、implicit 定義あるいは暗黙のパラメータを表す、すべての識別子 x が適しています。 2 つめは、implicit と印された暗黙のパラメータの型のコンパニオンモジュールのすべてのメンバーも適しています。 次の例は、monoid の add と unit 操作を使ってリストの要素の合計を計算する、メソッド sum を定義しています。暗黙の値がトップレベルではいけないことに注意してください。それらはテンプレートのメンバーでなければなりません。 abstract class SemiGroup[A] { def add(x A, y A) A } abstract class Monoid[A] extends SemiGroup[A] { def unit A } object ImplicitTest extends Application { implicit object StringMonoid extends Monoid[String] { def add(x String, y String) String = x concat y def unit String = "" } implicit object IntMonoid extends Monoid[Int] { def add(x Int, y Int) Int = x + y def unit Int = 0 } def sum[A](xs List[A])(implicit m Monoid[A]) A = if (xs.isEmpty) m.unit else m.add(xs.head, sum(xs.tail)) println(sum(List(1, 2, 3))) println(sum(List("a", "b", "c"))) } 次は Scala プログラムの出力です 6 abc Scala ひと巡り 内部クラス (Inner Classes) 原ページ Scala では、クラスは他のクラスをメンバーとして持てます。Java ライクな言語では、そのような内部クラスは取り囲むクラスのメンバーですが、Scala では反対に、そのような内部クラスは外側のオブジェクトへ束縛されます。違いを明らかにするために、グラフデータ型の実装概要を示します class Graph { class Node { var connectedNodes List[Node] = Nil def connectTo(node Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node connectedNodes } } } var nodes List[Node] = Nil def newNode Node = { val res = new Node nodes = res nodes res } } このプログラムで、グラフはノードのリストによって表されます。ノードは内部クラス Node のオブジェクトです。各ノードは 隣のリストを持っており、それはリスト connectedNodes 中に記憶されます。これでいくつかのノードをもち、ノードを付加的に(incrementally)連結できるグラフをセットアップできます。 object GraphTest extends Application { val g = new Graph val n1 = g.newNode val n2 = g.newNode val n3 = g.newNode n1.connectTo(n2) n3.connectTo(n1) } 次に、定義されるエンティティの型が何であるかを明示する型を用いて、例を補強します object GraphTest extends Application { val g Graph = new Graph val n1 g.Node = g.newNode val n2 g.Node = g.newNode val n3 g.Node = g.newNode n1.connectTo(n2) n3.connectTo(n1) } このコードは、ノードの型が、その外側のインスタンス(この例ではオブジェクト g )で前置されることを明らかにしています。今 2 つのグラフがあるとして、Scala の型システムは、一方のグラフ内で定義されたノードと他方のグラフのノードを混ぜることを許しません。なぜなら、他のグラフのノードは異なる型をもつからです。 次は不正なプログラムです object IllegalGraphTest extends Application { val g Graph = new Graph val n1 g.Node = g.newNode val n2 g.Node = g.newNode n1.connectTo(n2) // 正しい val h Graph = new Graph val n3 h.Node = h.newNode n1.connectTo(n3) // 不正! } Javaでは、上記サンプルプログラムの最後の行は正しいことに注意してください。Java は両方のグラフのノードに同じ型 Graph.Node を割り当てます。すなわち、Node はクラス Graph で前置されます(*1)。 Scalaでは、そのような型も表現でき、Graph#Node と書きます。もし異なるグラフのノードを連結できるようにしたければ、最初のグラフ実装の定義を次のように変える必要があります。 class Graph { class Node { var connectedNodes List[Graph#Node] = Nil def connectTo(node Graph#Node) { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node connectedNodes } } } var nodes List[Node] = Nil def newNode Node = { val res = new Node nodes = res nodes res } } このプログラムが、2 つの異なるグラフへのノードの張りつけを許さないことに注意してください。もしこの制限もなくしたければ、変数 nodes の型とメソッド newNode の戻り値型を Graph#Node に変える必要があります。 (*1)訳注: Scalaではクラス Graph ではなくオブジェクト g が前置されていて、 g.Node と h.Node はパスが異なるので異なる型を表すということ。 Scala ひと巡り ミックスインクラス合成 (Mixin Class Composition) 原ページ 単一継承のみをサポートする言語と対照して、Scala には、クラス再利用のためのより汎用的な概念があります。Scala では、クラスの新しいメンバー定義(すなわち、スーパークラス継承の差分)を再利用できます。これはミックスインクラス合成として表現されます。イテレータに関する次の抽象化を考えてみます。 abstract class AbsIterator { type T def hasNext Boolean def next T } 次に、メソッド foreach を用いて AbsIterator を展開するミックスインクラスについて考えます。ここで foreach は、イテレータが返す各要素に与えられた関数を適用します。ミックスインとして使用できるクラスを定義するのに、キーワード trait を使います。 trait RichIterator extends AbsIterator { def foreach(f T = Unit) { while (hasNext) f(next) } } 次は、与えられた文字列の文字を次々に返す、具象イテレータクラスです class StringIterator(s String) extends AbsIterator { type T = Char private var i = 0 def hasNext = i s.length() def next = { val ch = s charAt i; i += 1; ch } } StringIterator と RichIterator の機能を 1 つのクラスへ統合したいとします。これは単一継承とインタフェースだけではできません。両クラスともコードを伴うメンバー実装を含むからです。Scala では、ミックスインクラス合成を使ってできます。プログラマはクラス定義の差分 --- すなわち、継承さていれないすべての新しい定義 --- を再利用できます。この機構により、次のテストプログラムのようにして、RichIterator と StringIterator を統合できます。次は、与えられた文字列のすべての文字のカラムを印字します。 object StringIteratorTest { def main(args Array[String]) { class Iter extends StringIterator(args(0)) with RichIterator val iter = new Iter iter foreach println } } 関数 main 中の Iter クラスは、親の StringIterator と RichIterator をキーワード with を使ってミックスイン合成し、構築されています。最初の親は Iter のスーパークラスと呼ばれるのに対し、2 つめ(と、もしあればその他すべて)の親は、ミックスインと呼ばれます。 Scala ひと巡り 関数のネスト (Nested Functions) 原ページ Scala では、関数定義をネストできます。次のオブジェクトは、整数のリストから閾値未満の値を抽出する、filter 関数を提供します object FilterTest extends Application { def filter(xs List[Int], threshold Int) = { def process(ys List[Int]) List[Int] = if (ys.isEmpty) ys else if (ys.head threshold) ys.head process(ys.tail) else process(ys.tail) process(xs) } println(filter(List(1, 9, 2, 8, 3, 7, 4), 5)) } ネストされた関数 process が、filter のパラメータ値である外側のスコープ中で定義された変数 threshold を参照することに注意してください。 次はこのプログラムの出力です List(1,2,3,4) Scala ひと巡り 無名関数の構文 (Anonymous Function Syntax) 原ページ Scala は無名関数の定義について、比較的簡単な構文を提供します。次の式は、整数の後続関数を生成します (x Int) = x + 1 これは次の、無名クラス定義の略記表現です new Function1[Int, Int] { def apply(x Int) Int = x + 1 } 複数のパラメータをもつ関数も定義できます。 (x Int, y Int) = "(" + x + ", " + y + ")" あるいは、パラメータなしの関数 () = { System.getProperty("user.dir") } 関数の型を書くためのたいへん簡単な方法もあります。次は、上で定義した 3 つの関数の型です Int = Int (Int, Int) = String () = String この構文は、次の型の略記表現です Function1[Int, Int] Function2[Int, Int, String] Function0[String] Scala ひと巡り カリー化 (Currying) 原ページ メソッドは複数のパラメータリストを定義できます。メソッドは、パラメータリストの数より少ない形で呼び出される時には、その引数としてパラメータリストを失った関数をもたらします。 次は 1 つの例です object CurryTest extends Application { def filter(xs List[Int], p Int = Boolean) List[Int] = if (xs.isEmpty) xs else if (p(xs.head)) xs.head filter(xs.tail, p) else filter(xs.tail, p) def modN(n Int)(x Int) = ((x % n) == 0) val nums = List(1, 2, 3, 4, 5, 6, 7, 8) println(filter(nums, modN(2))) println(filter(nums, modN(3))) } 2 つの filter 呼び出しにおいて、メソッド modN が部分適用されることに注意してください; すなわち、その最初の引数だけが実際に適用されます。項 modN(2) は、型 Int = Boolean の関数をもたらし、それはこのように、関数 filter の 2 番目の引数に対する可能な候補となります。 次は、上記プログラムの出力です List(2,4,6,8) List(3,6) Scala ひと巡り 型依存クロージャの自動構築 (Automatic Type-Dependent Closure Construction) 原ページ uction) Scala では、メソッドのパラメータにパラメータなしの関数名を与えることができます。そのようなメソッドが呼ばれる時、パラメータなしの関数名に対する実際のパラメータは評価されず、代わりにパラメータなしの関数が渡されます。これは対応するパラメータの計算をカプセル化します(いわゆる、名前呼出し評価)。 次のコードはこのメカニズムを示します object TargetTest1 extends Application { def whileLoop(cond = Boolean)(body = Unit) Unit = if (cond) { body whileLoop(cond)(body) } var i = 10 whileLoop (i 0) { println(i) i -= 1 } } 関数 whileLoop は、2 つのパラメータ cond と body をとります。関数の適用時、実際のパラメータは評価されません。しかしその代わりに、whileLoop の本体中で形式上のパラメータが使われる毎に、暗黙のうちに生成されるパラメータなしの関数が評価されます。このように、このメソッド whileLoop は、再帰的な実装方式の Java ライクな while-loop を実装します。 中置/後置演算子 [27] とこのメカニズムを結びつけて、(洗練された構文を用いた)より複雑な文を作れます。 次は loop-unless 文の実装です object TargetTest2 extends Application { def loop(body = Unit) LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body = Unit) { def unless(cond = Boolean) { body if (!cond) unless(cond) } } var i = 10 loop { println("i = " + i) i -= 1 } unless (i == 0) } loop 関数はただループの本体を受けつけるだけであり、そして(この本体オブジェクトをカプセル化する)クラス LoopUnlessCond のインスタンスを返します。本体がまだ評価されないことに注意してください。クラス LoopUnlessCond はメソッド unless を持っており、それを中置演算子として使用できます。このように、新たなループ loop { stats } unless ( cond ) の、極めて自然な構文を作れます 次は、TargetTest2 を実行したときの出力です i = 10 i = 9 i = 8 i = 7 i = 6 i = 5 i = 4 i = 3 i = 2 i = 1 Scala ひと巡り オペレータ (Operators) 原ページ Scala では、ただ 1 つのパラメータをとるどのようなメソッドも中置演算子として使えます。 次は、3 つのメソッド and、or と negate を定義する classMyBool の定義です。 class MyBool(x Boolean) { def and(that MyBool) MyBool = if (x) that else this def or(that MyBool) MyBool = if (x) this else that def negate MyBool = new MyBool(!x) } ここで、and と or を中置演算子として使えます。 def not(x MyBool) = x negate; // ここではセミコロンが必要 def xor(x MyBool, y MyBool) = (x or y) and not(x and y) このコードの最初の行のように、パラメータなしのメソッドを後置演算子としても使用えます。2 番目の行は、新しい not 関数と同様に、and および or メソッドを使って xor 関数を定義します。この例で、中置演算子を使って xor 定義がいっそう理解しやすくなっています。 次は、より伝統的なオブジェクト指向プログラミング言語構文における、対応するコードです def not(x MyBool) = x.negate; // semicolon required here def xor(x MyBool, y MyBool) = x.or(y).and(x.and(y).negate) Scala ひと巡り 高階関数 (Higher-Order Functions) 原ページ Scala では、高階関数を定義できます。それらは、パラメータに他の関数をとるか、あるいは、その結果が関数であるような、関数です。 次は、他の関数 f と値 v をとり、関数 f を v に適用する、関数 apply です。 def apply(f Int = String, v Int) = f(v) もしコンテキスト上で必要なら、メソッドが関数へ自動的に特化(coerced 強制)されることに注意してください。 次は 1 つの例です class Decorator(left String, right String) { def layout[A](x A) = left + x.toString() + right } object FunTest extends Application { def apply(f Int = String, v Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) } 実行すると次の出力となります。 [7] この例で、メソッド decorator.layout は、メソッド apply が必要とするときに、型 Int = String の値へ自動的に特化されます。メソッド decorator.layout が多相的メソッドであり(すなわち、いくつかのシグニチャ型にわたっての抽象化)、Scala コンパイラは最初にそのメソッド型を適切にインスタンス化しなければならないことに注意してください。 Scala ひと巡り パッケージ (Packages) 原ページ パッケージはメンバークラス、オブジェクトとパッケージの集合を定義する特別なオブジェクトです。他のオブジェクトと異なり、パッケージは定義では導入できません。 パッケージング package p { ds } は、ds 中のすべての定義をその限定修飾名が p であるパッケージに、メンバーとして注入します。パッケージのメンバーはトップレベル定義と呼ばれます。もし ds 中の定義が private と印されていれば、そのパッケージ中の他のメンバーに対してのみ可視となります。 protected 修飾子をパッケージ識別子 p で限定できます(たとえば protected[p])。そのような修飾子を印されたメンバーは、パッケージ p 内のすべてのコードから同様にアクセス可能です。 p からの選択 p.m は、p からのインポートと同様、オブジェクトに関して機能します。しかし、他のオブジェクトと異なり、パッケージは値としては使用できません。モジュールあるいはクラス名と、同じ完全修飾名のパッケージは不正です。 パッケージング外でのトップレベル定義は、特別な空パッケージに注入されるとみなされます。このパッケージは、名前を付けることはできず、したがってインポートできません。しかし、空パッケージのメンバーは互いに限定修飾なしで可視です。 パッケージ節ではじまるコンパイル単位 package p ; stats は、ただ 1 つのパッケージング package p { stats } からなるコンパイル単位と同じです。 同じ Scala ソースファイル中で、複数のパッケージを宣言できます。 package p1 { object test extends Application { println("p1.test") } } package p2 { object test extends Application { println("p2.test") } } インポート節 インポート節は、import p.I の形をしています。ここで、インポート式 I は、限定修飾なしでアクセスできる、p のインポート可能なメンバー名の集合を決定します。たとえば 節 限定修飾なしで利用可能 import p._ p の全てのメンバー (Javaにおける import p.* と類似) import p.x p のメンバー x import p.{x = a} p のメンバー x を a にリネーム import p.{x, y} p のメンバー x と y import p1.p2.z p2 のメンバー z 。p2 自身は p1 のメンバー また、節 import p1._ , p2._ は、import p1._; import p2._ の略記表現です。 次は、すべてのコンパイル単位中に暗黙のうちに、この順番でインポートされます。 パッケージ java.lang、 パッケージ Scala と オブジェクト scala.Predef この順番において、後でインポートしたメンバーは、前にインポートしたメンバーを隠します。 Scala ひと巡り パターンマッチング (Pattern Matching) 原ページ Scala には、汎用的なパターンマッチング機構が組み込まれています。ファーストマッチ方式で、あらゆる種類のデータ上でマッチングさせることができます。 次は、整数値に対するマッチ方法を示す、小さな例です object MatchTest1 extends Application { def matchTest(x Int) String = x match { case 1 = "one" case 2 = "two" case _ = "many" } println(matchTest(3)) } ケース文のブロックは、整数を文字列にマップする関数を定義します。match キーワードは、オブジェクトに関数を適用する(上記のパターンマッチング関数のような)便利な方法を提供します。 次は、異なる型のパターンの値とマッチする、2 つめの例です object MatchTest2 extends Application { def matchTest(x Any) Any = x match { case 1 = "one" case "two" = 2 case y Int = "scala.Int" } println(matchTest("two")) } もし x が整数値 1 を参照するなら、最初のケースがマッチします。もし x が文字列 "two" と等しければ、2 つめのケースがマッチします。3 つめのケースは型付きパターンから成ります; それは任意の整数にマッチし、セレクター値 x を整数型の変数 y に束縛します。 Scala のパターンマッチング文は、ケースクラス [10]を介して表現される代数型上のマッチングにおいて、最も役に立ちます。 Scala ではまた、抽出子オブジェクト [59]中の unapply メソッドを使って、ケースクラスとは独立にパターンを定義できます。 Scala ひと巡り 多相的メソッド (Polymorphic Methods) 原ページ Scala 中のメソッドは、値と型の両方でパラメータ化できます。クラスレベルのように、値パラメータは丸括弧の対で囲み、他方、型パラメータは対の角括弧内で宣言します。 次は 1 つの例です object PolyTest extends Application { def dup[T](x T, n Int) List[T] = if (n == 0) Nil else x dup(x, n - 1) println(dup[Int](3, 4)) println(dup("three", 3)) } オブジェクト PolyTest 中のメソッド dup は、型 T と値パラメータ x T、n Int でパラメータ化されています。メソッド dup が呼び出されると、プログラマは必要とされるパラメータを提供しますが(上記プログラム中の 5 行目参照)、上記プログラムの 6 行目のように、プログラマは実際の型パラメータを明示的に与える必要はありません。Scala の型システムは、そのような型を推論できます。それは、与えられた値パラメータの型と、メソッドが呼ばれるコンテキストを調べることで、なされます。 トレイト Application は短いテストプログラムを書くために設計したのですが、JVM の出力コード最適化能力を動揺させるようなプログラムを書くことは避けるべきでしょう。この代わりに def main() を使ってください。 Scala ひと巡り 正規表現パターン (Regular Expression Patterns) 原ページ 右無視シーケンスパターン 右無視パターンは、Seq[A]のサブ型あるいは、(たとえば下記のような)反復する形式上のパラメータをもつケースクラスなどのデータ分解に役立つフィーチャーです。 Elem(prefix String, label String, attrs MetaData, scp NamespaceBinding, children Node*) これらの場合、Scala は、任意長のシーケンスを表すワイルドカード-星印 _ * を最右端にもつパターンを許しています。 次は、シーケンスの前部とマッチし、残りを変数 restへ束縛する、パターンマッチの例です。 object RegExpTest1 extends Application { def containsScala(x String) Boolean = { val z Seq[Char] = x z match { case Seq( s , c , a , l , a , rest @ _*) = println("rest is "+rest) true case Seq(_*) = false } } } 次に述べる理由により、前 Scala バージョンと違い、もう任意の正規表現は使用できません。 Scala から当面の間除かれた一般的な Regexp パターン 正当性の問題が見つかり、このフィーチャーは当面の間 Scala 言語から除かれています。もしユーザーコミュニティーからのリクエストがあれば、私たちはこれを改善した形で復活させるかもしれません。 私達の考えでは、正規表現パターンは私たちが見積もったほどには XML 処理に役立ちませんでした。現実の XML 処理アプリケーションでは、XPath ははるかに良い選択肢に思われます。変換処理あるいは正規表現パターンが、あまり使われずしかも取り除くことが難しい難解なパターンに対していくつかのバグをもつということを見つけたとき、言語を単純化する時が来たと私達は判断しました。 前 はじめ 次
https://w.atwiki.jp/ndsdev/
@wikiへようこそ ウィキはみんなで気軽にホームページ編集できるツールです。 このページは自由に編集することができます。 メールで送られてきたパスワードを用いてログインすることで、各種変更(サイト名、トップページ、メンバー管理、サイドページ、デザイン、ページ管理、等)することができます まずはこちらをご覧ください。 @wikiの基本操作 用途別のオススメ機能紹介 @wikiの設定/管理 おすすめ機能 気になるニュースをチェック 関連するブログ一覧を表示 その他にもいろいろな機能満載!! @wikiプラグイン @wiki便利ツール @wiki構文 @wikiプラグイン一覧 バグ・不具合を見つけたら? 要望がある場合は? お手数ですが、メールでお問い合わせください。 分からないことは? @wiki ご利用ガイド よくある質問 @wiki更新情報 @wikiへお問い合わせ 等をご活用ください その他お勧めサービスについて フォーラム型の無料掲示板は@bbをご利用ください 2ch型の無料掲示板は@chsをご利用ください お絵かき掲示板は@paintをご利用ください その他の無料掲示板は@bbsをご利用ください 無料ブログ作成は@WORDをご利用ください CGIゲームが設置できる無料ホームページ作成は@PAGESをご利用ください
https://w.atwiki.jp/tmiya/pages/141.html
Scala アクター 簡易チュートリアル (Scala Actors A Short Tutorial) By phaller Created 2007-05-24, 08 26 はじめに (Introduction) マルチコアプロセッサの到来で並行プログラミングは不可欠になりました。並行性に関する Scala の主要な構文はアクターです。アクターは基本的に、メッセージ交換で通信する並行プロセスです。アクターは、メッセージ送信に関連するメソッドを起動する、アクティブなオブジェクトの形態と見ることもできます。 Scala アクターライブラリは、同期、非同期メッセージ送信の両方を提供します(前者は、複数の非同期メッセージ交換によって実装されます)。さらに、アクターは、リクエストを非同期に処理するフューチャ(*1)を使って通信しますが、その応答を待つことを可能にする表現(フューチャ)を返します。 このチュートリアルの主な目的は、すぐにコンパイルできて Scala 2.4 以降で実行できる、いくつかの完全なサンプルプログラムをウォークスルーすることです。 (*1)訳注:フューチャについては Scala By Example 17.3参照 最初の例 (First Example) 最初の例は、一連のメッセージを交換して終了する 2 つのアクターから成ります。最初のアクターは "ping" メッセージを 2 番目のアクターに送り、するとそれは "pong" メッセージを返送します。( 各受信 "ping"メッセージ に 1 つの "pong" メッセージ)。 はじめにアクターによって送受信されるメッセージを定義します。この場合、シングルトンオブジェクトが使えます(より先進的なプログラムでは、メッセージをパラメータ化します)。パターンマッチィングを使いたいので、各メッセージは case object (ケースオブジェクト)です case object Ping case object Pong case object Stop ping アクターは、pong アクターに Ping メッセージを送ることで交換処理を開始します。Pong メッセージは pong アクターからの応答です。ping アクターは、特定の数の Ping メッセージを送り終えると、pong アクターに Stop メッセージを送ります。 Scala アクターライブラリのすべてのクラス、オブジェクトとトレイトは、scala.actors パッケージにあります。このパッケージから Actor クラスをインポートし、拡張して独自のカスタムアクターを定義するのに使います。また、それは多くの役に立つアクター操作を含むので、Actor オブジェクトのすべてのメンバーをインポートします import scala.actors.Actor import scala.actors.Actor._ アクターは、Actor クラスのサブクラスをインスタンス化して生成できる、普通のオブジェクトです。Actor をサブクラス化し、その抽象 act メソッドを実装することで、ping アクターの振る舞いを定義します class Ping(count int, pong Actor) extends Actor { def act() { var pingsLeft = count - 1 pong ! Ping while (true) { receive { case Pong = if (pingsLeft % 1000 == 0) Console.println("Ping pong") if (pingsLeft 0) { pong ! Ping pingsLeft -= 1 } else { Console.println("Ping stop") pong ! Stop exit() } } } } } 送るべき Ping メッセージの数と pong アクターは、コンストラクタの引数として渡されます。無限ループ中の receive メソッドの呼び出しは、Pong メッセージがアクターに送られるまで、アクターをサスペンドします。この場合、メッセージはアクターのメールボックスから取り除かれ、対応する、矢印の右側のアクションが実行されます。 pingsLeft がゼロより大きい場合は、! 送信演算子を使って Ping メッセージを pong アクターへ送り、pingsLeft カウンタを減じます。pingsLeft カウンタがゼロになったら、pong アクターへ Stop メッセージを送り、exit()を呼び出して現在のアクター実行を終了させます。 pong アクター用のクラスも同じように定義できます class Pong extends Actor { def act() { var pongCount = 0 while (true) { receive { case Ping = if (pongCount % 1000 == 0) Console.println("Pong ping "+pongCount) sender ! Pong pongCount = pongCount + 1 case Stop = Console.println("Pong stop") exit() } } } } ここで、注目すべき点が 1 つあります。Ping メッセージを受信して、Pong メッセージを sender アクターに送りますが、それは我々のクラスのどこにも定義されていません! 実は、それは Actor クラスのメソッドです。sender を使えば、現在のアクターが最後に受け取ったメッセージを送ったアクターを参照できます。これにより、メッセージの引数として明示的に送信者を渡さなくても済みます。 あとはアクタークラスを定義すれば、それらを使う Scala アプリケーションの生成準備完了です。 object pingpong extends Application { val pong = new Pong val ping = new Ping(100000, pong) ping.start pong.start } Java スレッドと同じように、アクターは start メソッドの呼び出しで始めます。 動かしましょう! (Let s run it!) 完全な例は、doc/scala-devel/scala/examples/actors/pingpong.scala 下の Scala ディストリビューションに含まれています。 次は、これをコンパイル、実行する方法です $ scalac pingpong.scala $ scala -cp . examples.actors.pingpong Pong ping 0 Ping pong Pong ping 1000 Ping pong Pong ping 2000 ... Ping stop Pong stop スレッド レスに! (Make it Thread-less!) アクターはスレッドプール上で実行されます。最初は、4 つのワーカースレッドがあります。もしすべてのワーカースレッドがブロックされて、まだ処理すべきタスクがあれば、スレッドプールは増大します。理想的には、スレッドプールの大きさは計算機の処理系コアの数に一致します。 アクターが、receive のような(あるいは同等の wait)スレッドをブロックする操作を呼び出すと、現在のアクター(self)を実行しているワーカースレッドはブロックされます。これは基本的に、アクターがブロックされるスレッドであることを意味します。たいていの JVM は標準的なハードウェア上では数千スレッド以上は処理できないので、使いたいアクター数への依存は避けたいことでしょう。 スレッド-ブロッキング操作は、新しいメッセージを待つ react (イベントベースの receive の仲間)を使って避けることができます。しかし、支払うべき(通常は少しの)代償があります react は決して戻ってきません。現実には、メッセージへの応答の終わりに、アクターの計算の残りを含む何らかの関数を呼び出す必要があるということです。while ループ内で react を使ってもうまく機能しないことに注意してください! しかし、ループは一般的ですから、このための特別な、loop 関数形のライブラリサポートがあります。次のように使えます。 loop { react { case A = ... case B = ... } } react の呼び出しをネストできることに注意してください。それにより、次のようにシーケンスの複数のメッセージを受信できます。 react { case A = ... case B = react { // if we get a B we also want a C case C = ... } } ping と pong アクターをスレッドレスにするには、たんに while(true)を loop で、receive を react で置き換えれば十分です。例えば、次は pong アクターの修正版 act メソッドです def act() { var pongCount = 0 loop { react { case Ping = if (pongCount % 1000 == 0) Console.println("Pong ping "+pongCount) sender ! Pong pongCount = pongCount + 1 case Stop = Console.println("Pong stop") exit() } } } 2 つめの例 (Second Example) 2 つめ例として、作り出された値のシーケンスを読み出す producers の抽象化を書くつもりです。それは標準的なイテレータインターフェースを提供します。 特定の producers は、抽象 produceValues メソッドを実装することで、定義します。個々の値は、produce メソッドを使って作り出します。クラス producer は両方のメソッドを継承します。例えば、行きがけ順(pre-order)のツリーに含まれる値を作り出す producer は次のように定義できます class PreOrder(n Tree) extends Producer[int] { def produceValues = traverse(n) def traverse(n Tree) { if (n != null) { produce(n.elem) traverse(n.left) traverse(n.right) } } Producer は、2 つのアクター producer アクターと coordinator アクターを用いて実装されています。次は producer アクターの実装方法を示します。 abstract class Producer[T] { protected def produceValues unit protected def produce(x T) { coordinator ! Some(x) receive { case Next = } } private val producer Actor = actor { receive { case Next = produceValues coordinator ! None } } ... } producer アクターの定義方法に注目してください。今回は、わざわざ Actor の特別のサブクラスを生成して、その act メソッドを実装しようとはしませんでした。その代わり、たんに actor 関数を使ってインラインでアクターの振る舞いを定義します。多分、これはずっと簡潔です! さらに、actor を使って定義したアクターは自動的に始まるので、start メソッドを起動する必要がありません! それで、producer はどのように動作するのでしょうか? Next メッセージを受け取ると、(抽象) produceVaules メソッドを実行し、それは今度は、produce メソッドを呼び出します。この結果、値のシーケンスが Some メッセージにラップされて coordinator へ送られます。シーケンスのお終いは None メッセージです。Some と None は Scala の標準 Option クラスの 2 つのケース(訳注 ケースクラス/ケースオブジェクト)です。 coordinatorはクライアントからの要求と producer から来る値を同期させます。次のように実装できます private val coordinator Actor = actor { loop { react { case Next = producer ! Next reply { receive { case x Option[_] = x } } case Stop = exit( stop) } } } Next メッセージ用のハンドラ中で、受信 Option 値をある要求側 actor へ返すために、reply を使っていることに注意してください。このことは、次のセクションで説明するつもりです。話を元に戻して... イテレータインターフェース (The Iterator Interface) 我々は producers を標準的なイテレータとして使えることを望みます。そのために、驚くなかれ、イテレータ返す iterator メソッドを実装します。その hasNext と next メソッドは、仕事を遂行するために coordinator アクターにメッセージを送ります。見てみましょう def iterator = new Iterator[T] { private var current Any = Undefined private def lookAhead = { if (current == Undefined) current = coordinator !? Next current } def hasNext boolean = lookAhead match { case Some(x) = true case None = { coordinator ! Stop; false } } def next T = lookAhead match { case Some(x) = current = Undefined; x.asInstanceOf[T] } } 非公開の lookAhead メソッドを使ってイテレータロジックを実装します。next 値がまだ未探索の場合は、current 変数は単なるプレースホルダーオブジェクトである値 Undefined を持ちます。 private val Undefined = new Object ちょっと興味を引くことが lookAhead メソッドの中にあります。current 値が Undefined のとき、これは next 値を手に入れなければならないことを意味します。そのために、同期メッセージ送信演算子 !? を使います。これは coordinatorに Next メッセージを送信しますが、しかし、通常の(非同期)メッセージ送信のように戻る代わりに、coordinator からの応答を待ちます。応答は !? の戻り値です。!? を使って送られたメッセージは、reply を使って応答されます。 sender に単純にメッセージを送っても機能しないことに注意してください! それは、!? がメールボックスの代わりに 非公開の reply チャネルからのメッセージ受信を待つからです。これは "true" 応答を、たまたまメールボックスにある古いメッセージに起因する "fake(偽物)" から区別するために必要です。 producers の例は doc/scala-devel/scala/examples/actors/producers.scala 下の Scala ディストリビューションに同じく含まれています。
https://w.atwiki.jp/ndsdev/pages/8.html
@wikiにはいくつかの便利なプラグインがあります。 アーカイブ コメント ニュース 動画(Youtube) 編集履歴 関連ブログ これ以外のプラグインについては@wikiガイドをご覧ください = http //atwiki.jp/guide/
https://w.atwiki.jp/neetsdkasu/pages/36.html
バージョン管理に関するメモ バージョン管理の種類 ※集中型管理 CVS Subvertion (svn) ※分散型管理 Git Mercurial (hg) Bazaar (bzr) ※他にも色々あるらしい 用語 リポジトリ コミット ブランチ Git Subversion (SVN) バージョン管理 .
https://w.atwiki.jp/kiake77/pages/8.html
@wikiにはいくつかの便利なプラグインがあります。 アーカイブ コメント ニュース 動画(Youtube) 編集履歴 関連ブログ これ以外のプラグインについては@wikiガイドをご覧ください = http //atwiki.jp/guide/