Go言語で手動オブジェクト指向
仮想関数をインターフェースに書き出して、Self経由で呼び出す方式。
手順は、
- 構造体とインターフェースを対にして作る
- それぞれに埋め込みで継承していく
- コンストラクタ関数で、Selfを伝搬させていく
こんなダサくて効率の悪いことは普通やらないが、GUIフレームワークのようにオブジェクト指向が合うものには、部分的に似たような構造が使われている感じがする。
package main import ( "fmt" ) type IA interface { MethodA() } type A struct { Self IA } func (a *A) MethodA() { fmt.Println("A.MethodA") } func (a *A) CallMethodA() { fmt.Println("A.CallMethodA") a.Self.MethodA() // Self経由で呼び出す } func NewA(self IA) *A { a := &A{} if self != nil { a.Self = self } else { a.Self = a } return a } type IB interface { IA MethodB() } type B struct { *A Self IB Super IA } func (b *B) MethodA() { fmt.Println("B.MethodA") b.Super.MethodA() } func (b *B) MethodB() { fmt.Println("B.MethodB") } func NewB(self IB) *B { b := &B{} if self != nil { b.Self = self } else { b.Self = b } b.A = NewA(b.Self) b.Super = b.A return b } type IC interface { IB } type C struct { *B Self IC Super IB } func (c *C) MethodB() { fmt.Println("C.MethodB") } func NewC(self IC) *C { c := &C{} if self != nil { c.Self = self } else { c.Self = c } c.B = NewB(c.Self) c.Super = c.B return c } type ID interface { IC } type D struct { *C Self ID Super IC } func (d *D) MethodA() { fmt.Println("D.MethodA") d.Super.MethodA() } func NewD(self ID) *D { d := &D{} if self != nil { d.Self = self } else { d.Self = d } d.C = NewC(d.Self) d.Super = d.C return d } func main() { d := NewD(nil) d.MethodA() // D.MethodA // B.MethodA // A.MethodA d.CallMethodA() // A.CallMethodA // D.MethodA // B.MethodA // A.MethodA d.MethodB() // C.MethodB }
mingw版ruby(64bit)にcurbとrmagickのgemをインストール
RubyInstaller(x64) での場合
rmagickのインストール
ftp://ftp.imagemagick.org/pub/ImageMagick/binaries/
から、ImageMagick-6.9.5-Q16-x64-dll.exeをダウンロード、インストール
(ImageMagick-7.0.3-0はダメだったので)
gemのインストール
gem install rmagick -- '--with-opt-dir="C:\dev\cmd\ImageMagick-6.9.5-Q16"'
curbのインストール
https://curl.haxx.se/gknw.net/7.40.0/dist-w64/curl-7.40.0-devel-mingw64.zip
↑のファイルをダウンロードして、適当な場所に配置。
動作テスト
require 'curb' require 'rmagick' easy = Curl::Easy.download("http://www.imagemagick.org/image/wizard.jpg") p easy.downloaded_content_length #=> 68305.0 image = Magick::ImageList.new("wizard.jpg").first p [image.columns, image.rows] #=> [265, 352]
KyotoCabinetのruby拡張をmingwでビルド(2)
RubyInstaller(x64)のRubyでkyotocabinetの拡張を使うためにビルドしようとしたが、なかなかうまくいかなかった。
結局、かなり滅茶苦茶なやり方でビルドしたので、自分以外の役には立たないかもしれない。
1.準備
2. Kyoto Cabinet のビルド・インストール
kyotocabinet-1.2.76.tar.gzをダウンロード、展開。
configureを編集 (置換)
/usr/local/include → /mingw64/include
/usr/local/lib → /mingw64/lib
kcthread.ccの編集 (置換)
(::DWORD)opq_ → (::DWORD_PTR)opq_
ビルド
./configure --prefix=/mingw64 --enable-lzo make make install
3. KyotoCabinet の ruby拡張をビルド・インストール
kyotocabinet-ruby-1.32.tar.gzをダウンロード、展開。
各種ファイルの編集
・extconf.rbとtest.rbの Config を RbConfig に置換。
・kyotocabinet.ccの「#define _KC_YARV_」をコメントアウト。
(※ちなみにrb_thread_blocking_regionの所をrb_thread_call_without_gvlで書き直してみたら、test.rbでbugに遭遇。)
ruby extconf.rb
でMakefileを作成。
ここのrubyは、RubyInstallerでインストールしたruby。
パスが通ってなかったら、/c/ruby23-x64/bin/ruby みたいに書けばいいはず。
MakefileのLIBSを編集して、ビルド
余計なdllを必要としないように試行錯誤。
LIBS = $(LIBRUBYARG_SHARED) -lkyotocabinet -llzo2 -lz -lregex -lstdc++ -lpthread -lm -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
↑この部分を、↓に書き換え。
LIBS = $(LIBRUBYARG_SHARED) -lkyotocabinet -lz -static-libgcc -Wl,-Bstatic -llzo2 -lregex -lstdc++ -lpthread -lm -Wl,-Bdynamic -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi
ビルド、テスト
make make install ruby test.rb
テストはwickedの所が全部failed。大丈夫なのかな?
window message
適当に抜き出しただけ
0 | WM_NULL |
1 | WM_CREATE |
2 | WM_DESTROY |
3 | WM_MOVE |
5 | WM_SIZE |
6 | WM_ACTIVATE |
7 | WM_SETFOCUS |
8 | WM_KILLFOCUS |
10 | WM_ENABLE |
11 | WM_SETREDRAW |
12 | WM_SETTEXT |
13 | WM_GETTEXT |
14 | WM_GETTEXTLENGTH |
15 | WM_PAINT |
16 | WM_CLOSE |
17 | WM_QUERYENDSESSION |
18 | WM_QUIT |
19 | WM_QUERYOPEN |
20 | WM_ERASEBKGND |
21 | WM_SYSCOLORCHANGE |
22 | WM_ENDSESSION |
24 | WM_SHOWWINDOW |
26 | WM_WININICHANGE |
26 | WM_SETTINGCHANGE |
27 | WM_DEVMODECHANGE |
28 | WM_ACTIVATEAPP |
29 | WM_FONTCHANGE |
30 | WM_TIMECHANGE |
31 | WM_CANCELMODE |
32 | WM_SETCURSOR |
33 | WM_MOUSEACTIVATE |
34 | WM_CHILDACTIVATE |
35 | WM_QUEUESYNC |
36 | WM_GETMINMAXINFO |
38 | WM_PAINTICON |
39 | WM_ICONERASEBKGND |
40 | WM_NEXTDLGCTL |
42 | WM_SPOOLERSTATUS |
43 | WM_DRAWITEM |
44 | WM_MEASUREITEM |
45 | WM_DELETEITEM |
46 | WM_VKEYTOITEM |
47 | WM_CHARTOITEM |
48 | WM_SETFONT |
49 | WM_GETFONT |
50 | WM_SETHOTKEY |
51 | WM_GETHOTKEY |
55 | WM_QUERYDRAGICON |
57 | WM_COMPAREITEM |
61 | WM_GETOBJECT |
65 | WM_COMPACTING |
68 | WM_COMMNOTIFY |
70 | WM_WINDOWPOSCHANGING |
71 | WM_WINDOWPOSCHANGED |
72 | WM_POWER |
74 | WM_COPYDATA |
75 | WM_CANCELJOURNAL |
78 | WM_NOTIFY |
80 | WM_INPUTLANGCHANGEREQUEST |
81 | WM_INPUTLANGCHANGE |
82 | WM_TCARD |
83 | WM_HELP |
84 | WM_USERCHANGED |
85 | WM_NOTIFYFORMAT |
123 | WM_CONTEXTMENU |
124 | WM_STYLECHANGING |
125 | WM_STYLECHANGED |
126 | WM_DISPLAYCHANGE |
127 | WM_GETICON |
128 | WM_SETICON |
129 | WM_NCCREATE |
130 | WM_NCDESTROY |
131 | WM_NCCALCSIZE |
132 | WM_NCHITTEST |
133 | WM_NCPAINT |
134 | WM_NCACTIVATE |
135 | WM_GETDLGCODE |
136 | WM_SYNCPAINT |
160 | WM_NCMOUSEMOVE |
161 | WM_NCLBUTTONDOWN |
162 | WM_NCLBUTTONUP |
163 | WM_NCLBUTTONDBLCLK |
164 | WM_NCRBUTTONDOWN |
165 | WM_NCRBUTTONUP |
166 | WM_NCRBUTTONDBLCLK |
167 | WM_NCMBUTTONDOWN |
168 | WM_NCMBUTTONUP |
169 | WM_NCMBUTTONDBLCLK |
171 | WM_NCXBUTTONDOWN |
172 | WM_NCXBUTTONUP |
173 | WM_NCXBUTTONDBLCLK |
254 | WM_INPUT_DEVICE_CHANGE |
255 | WM_INPUT |
256 | WM_KEYDOWN |
256 | WM_KEYFIRST |
257 | WM_KEYUP |
258 | WM_CHAR |
259 | WM_DEADCHAR |
260 | WM_SYSKEYDOWN |
261 | WM_SYSKEYUP |
262 | WM_SYSCHAR |
263 | WM_SYSDEADCHAR |
265 | WM_KEYLAST |
265 | WM_WNT_CONVERTREQUESTEX |
265 | WM_UNICHAR |
266 | WM_CONVERTREQUEST |
267 | WM_CONVERTRESULT |
268 | WM_INTERIM |
269 | WM_IME_STARTCOMPOSITION |
270 | WM_IME_ENDCOMPOSITION |
271 | WM_IME_KEYLAST |
271 | WM_IME_COMPOSITION |
272 | WM_INITDIALOG |
273 | WM_COMMAND |
274 | WM_SYSCOMMAND |
275 | WM_TIMER |
276 | WM_HSCROLL |
277 | WM_VSCROLL |
278 | WM_INITMENU |
279 | WM_INITMENUPOPUP |
287 | WM_MENUSELECT |
288 | WM_MENUCHAR |
289 | WM_ENTERIDLE |
290 | WM_MENURBUTTONUP |
291 | WM_MENUDRAG |
292 | WM_MENUGETOBJECT |
293 | WM_UNINITMENUPOPUP |
294 | WM_MENUCOMMAND |
295 | WM_CHANGEUISTATE |
296 | WM_UPDATEUISTATE |
297 | WM_QUERYUISTATE |
306 | WM_CTLCOLORMSGBOX |
307 | WM_CTLCOLOREDIT |
308 | WM_CTLCOLORLISTBOX |
309 | WM_CTLCOLORBTN |
310 | WM_CTLCOLORDLG |
311 | WM_CTLCOLORSCROLLBAR |
312 | WM_CTLCOLORSTATIC |
512 | WM_MOUSEFIRST |
512 | WM_MOUSEMOVE |
513 | WM_LBUTTONDOWN |
514 | WM_LBUTTONUP |
515 | WM_LBUTTONDBLCLK |
516 | WM_RBUTTONDOWN |
517 | WM_RBUTTONUP |
518 | WM_RBUTTONDBLCLK |
519 | WM_MBUTTONDOWN |
520 | WM_MBUTTONUP |
521 | WM_MBUTTONDBLCLK |
522 | WM_MOUSEWHEEL |
523 | WM_XBUTTONDOWN |
524 | WM_XBUTTONUP |
525 | WM_MOUSELAST |
525 | WM_XBUTTONDBLCLK |
526 | WM_MOUSEHWHEEL |
528 | WM_PARENTNOTIFY |
529 | WM_ENTERMENULOOP |
530 | WM_EXITMENULOOP |
531 | WM_NEXTMENU |
532 | WM_SIZING |
533 | WM_CAPTURECHANGED |
534 | WM_MOVING |
536 | WM_POWERBROADCAST |
537 | WM_DEVICECHANGE |
544 | WM_MDICREATE |
545 | WM_MDIDESTROY |
546 | WM_MDIACTIVATE |
547 | WM_MDIRESTORE |
548 | WM_MDINEXT |
549 | WM_MDIMAXIMIZE |
550 | WM_MDITILE |
551 | WM_MDICASCADE |
552 | WM_MDIICONARRANGE |
553 | WM_MDIGETACTIVE |
560 | WM_MDISETMENU |
561 | WM_ENTERSIZEMOVE |
562 | WM_EXITSIZEMOVE |
563 | WM_DROPFILES |
564 | WM_MDIREFRESHMENU |
640 | WM_IME_REPORT |
641 | WM_IME_SETCONTEXT |
642 | WM_IME_NOTIFY |
643 | WM_IME_CONTROL |
644 | WM_IME_COMPOSITIONFULL |
645 | WM_IME_SELECT |
646 | WM_IME_CHAR |
648 | WM_IME_REQUEST |
656 | WM_IMEKEYDOWN |
656 | WM_IME_KEYDOWN |
657 | WM_IMEKEYUP |
657 | WM_IME_KEYUP |
672 | WM_NCMOUSEHOVER |
673 | WM_MOUSEHOVER |
674 | WM_NCMOUSELEAVE |
675 | WM_MOUSELEAVE |
689 | WM_WTSSESSION_CHANGE |
704 | WM_TABLET_FIRST |
735 | WM_TABLET_LAST |
768 | WM_CUT |
769 | WM_COPY |
770 | WM_PASTE |
771 | WM_CLEAR |
772 | WM_UNDO |
773 | WM_RENDERFORMAT |
774 | WM_RENDERALLFORMATS |
775 | WM_DESTROYCLIPBOARD |
776 | WM_DRAWCLIPBOARD |
777 | WM_PAINTCLIPBOARD |
778 | WM_VSCROLLCLIPBOARD |
779 | WM_SIZECLIPBOARD |
780 | WM_ASKCBFORMATNAME |
781 | WM_CHANGECBCHAIN |
782 | WM_HSCROLLCLIPBOARD |
783 | WM_QUERYNEWPALETTE |
784 | WM_PALETTEISCHANGING |
785 | WM_PALETTECHANGED |
786 | WM_HOTKEY |
791 | WM_PRINT |
792 | WM_PRINTCLIENT |
793 | WM_APPCOMMAND |
794 | WM_THEMECHANGED |
797 | WM_CLIPBOARDUPDATE |
798 | WM_DWMCOMPOSITIONCHANGED |
799 | WM_DWMNCRENDERINGCHANGED |
800 | WM_DWMCOLORIZATIONCOLORCHANGED |
801 | WM_DWMWINDOWMAXIMIZEDCHANGE |
831 | WM_GETTITLEBARINFOEX |
856 | WM_HANDHELDFIRST |
863 | WM_HANDHELDLAST |
864 | WM_AFXFIRST |
895 | WM_AFXLAST |
896 | WM_PENWINFIRST |
911 | WM_PENWINLAST |
992 | WM_DDE_FIRST |
992 | WM_DDE_INITIATE |
993 | WM_DDE_TERMINATE |
994 | WM_DDE_ADVISE |
995 | WM_DDE_UNADVISE |
996 | WM_DDE_ACK |
997 | WM_DDE_DATA |
998 | WM_DDE_REQUEST |
999 | WM_DDE_POKE |
1000 | WM_DDE_LAST |
1000 | WM_DDE_EXECUTE |
1024 | WM_CAP_START |
1024 | WM_USER |
1024 | WM_PSD_PAGESETUPDLG |
1025 | WM_CHOOSEFONT_GETLOGFONT |
1025 | WM_PSD_FULLPAGERECT |
1025 | WM_CAP_GET_CAPSTREAMPTR |
1026 | WM_PSD_MINMARGINRECT |
1026 | WM_CAP_SET_CALLBACK_ERRORA |
1026 | WM_CAP_SET_CALLBACK_ERROR |
1027 | WM_PSD_MARGINRECT |
1027 | WM_CAP_SET_CALLBACK_STATUS |
1027 | WM_CAP_SET_CALLBACK_STATUSA |
1028 | WM_CAP_SET_CALLBACK_YIELD |
1028 | WM_PSD_GREEKTEXTRECT |
1029 | WM_PSD_ENVSTAMPRECT |
1029 | WM_CAP_SET_CALLBACK_FRAME |
1030 | WM_CAP_SET_CALLBACK_VIDEOSTREAM |
1030 | WM_PSD_YAFULLPAGERECT |
1031 | WM_CAP_SET_CALLBACK_WAVESTREAM |
1032 | WM_CAP_GET_USER_DATA |
1033 | WM_CAP_SET_USER_DATA |
1034 | WM_CAP_DRIVER_CONNECT |
1035 | WM_CAP_DRIVER_DISCONNECT |
1036 | WM_CAP_DRIVER_GET_NAME |
1036 | WM_CAP_DRIVER_GET_NAMEA |
1037 | WM_CAP_DRIVER_GET_VERSION |
1037 | WM_CAP_DRIVER_GET_VERSIONA |
1038 | WM_CAP_DRIVER_GET_CAPS |
1044 | WM_CAP_FILE_SET_CAPTURE_FILE |
1044 | WM_CAP_FILE_SET_CAPTURE_FILEA |
1045 | WM_CAP_FILE_GET_CAPTURE_FILEA |
1045 | WM_CAP_FILE_GET_CAPTURE_FILE |
1046 | WM_CAP_FILE_ALLOCATE |
1047 | WM_CAP_FILE_SAVEASA |
1047 | WM_CAP_FILE_SAVEAS |
1048 | WM_CAP_FILE_SET_INFOCHUNK |
1049 | WM_CAP_FILE_SAVEDIB |
1049 | WM_CAP_FILE_SAVEDIBA |
1054 | WM_CAP_EDIT_COPY |
1059 | WM_CAP_SET_AUDIOFORMAT |
1060 | WM_CAP_GET_AUDIOFORMAT |
1065 | WM_CAP_DLG_VIDEOFORMAT |
1066 | WM_CAP_DLG_VIDEOSOURCE |
1067 | WM_CAP_DLG_VIDEODISPLAY |
1068 | WM_CAP_GET_VIDEOFORMAT |
1069 | WM_CAP_SET_VIDEOFORMAT |
1070 | WM_CAP_DLG_VIDEOCOMPRESSION |
1074 | WM_CAP_SET_PREVIEW |
1075 | WM_CAP_SET_OVERLAY |
1076 | WM_CAP_SET_PREVIEWRATE |
1077 | WM_CAP_SET_SCALE |
1078 | WM_CAP_GET_STATUS |
1079 | WM_CAP_SET_SCROLL |
1084 | WM_CAP_GRAB_FRAME |
1085 | WM_CAP_GRAB_FRAME_NOSTOP |
1086 | WM_CAP_SEQUENCE |
1087 | WM_CAP_SEQUENCE_NOFILE |
1088 | WM_CAP_SET_SEQUENCE_SETUP |
1089 | WM_CAP_GET_SEQUENCE_SETUP |
1090 | WM_CAP_SET_MCI_DEVICEA |
1090 | WM_CAP_SET_MCI_DEVICE |
1091 | WM_CAP_GET_MCI_DEVICEA |
1091 | WM_CAP_GET_MCI_DEVICE |
1092 | WM_CAP_STOP |
1093 | WM_CAP_ABORT |
1094 | WM_CAP_SINGLE_FRAME_OPEN |
1095 | WM_CAP_SINGLE_FRAME_CLOSE |
1096 | WM_CAP_SINGLE_FRAME |
1104 | WM_CAP_PAL_OPENA |
1104 | WM_CAP_PAL_OPEN |
1105 | WM_CAP_PAL_SAVE |
1105 | WM_CAP_PAL_SAVEA |
1106 | WM_CAP_PAL_PASTE |
1107 | WM_CAP_PAL_AUTOCREATE |
1108 | WM_CAP_PAL_MANUALCREATE |
1109 | WM_CAP_SET_CALLBACK_CAPCONTROL |
1124 | WM_CAP_UNICODE_START |
1125 | WM_CHOOSEFONT_SETLOGFONT |
1126 | WM_CHOOSEFONT_SETFLAGS |
1126 | WM_CAP_SET_CALLBACK_ERRORW |
1127 | WM_CAP_SET_CALLBACK_STATUSW |
1136 | WM_CAP_DRIVER_GET_NAMEW |
1137 | WM_CAP_DRIVER_GET_VERSIONW |
1144 | WM_CAP_FILE_SET_CAPTURE_FILEW |
1145 | WM_CAP_FILE_GET_CAPTURE_FILEW |
1147 | WM_CAP_FILE_SAVEASW |
1149 | WM_CAP_FILE_SAVEDIBW |
1190 | WM_CAP_SET_MCI_DEVICEW |
1191 | WM_CAP_GET_MCI_DEVICEW |
1204 | WM_CAP_PAL_OPENW |
1205 | WM_CAP_UNICODE_END |
1205 | WM_CAP_PAL_SAVEW |
1205 | WM_CAP_END |
32768 | WM_APP |
OpenMP
inf
※VCの場合はfloat.hに_finiteがあることがわかった。
#include <iostream> #include <cmath> using namespace std; int main() { cout << log10(0) << endl; // -inf cout << isinf(log10(0)) << endl; // 1 cout << isfinite(log10(0)) << endl; // 0 cout << (int)log10(0) << endl; // -2147483648 cout << (unsigned int)log10(0) << endl; // 0 return 0; }
引数テスト
function funcA(a, b) { Services.console.logStringMessage([(typeof a), (typeof b)]); } var h = {}; funcA(1, 2); //=> number,number funcA(3); //=> number,undefined funcA(4, h['x']); //=> number,undefined funcA(h['x'], 5); //=> undefined,number