人力
     @emasaka
       #tqrk02
入力
     @emasaka
       #tqrk02
Introduce Myself

   自己紹介
Occupation

   職業
FREE
 無職
Period

 以上
Main Topic

  本題
Termtter
Troubles happens
 around “Input”

入力まわりはトラブルの巣
And

そして
We hopes to extend
 “Input” by Ruby

 入力をRubyで拡張したい
Example: Prompt the number of
          characters




 例:文字数をプロンプトに表示
                      ※画面は合成です
Example: Auto Complete




例:自動補完
                  ※画面は合成です
For that purpose

  そのために
Extend readline by Ruby?

   readlineをRubyで拡張?
Have to handle...

● C functions
● C variables

● C datas



    Cの関数、Cの変数、Cのデータ
    を扱わなくちゃならない
Port readline by Ruby?

 readlineをRubyに移植?
Many codes
$ cat *.[ch] | wc ­l
28955




        大量のコード
Many global variables
$ ruby ­ne 'next if /#|f|./; 
print gsub(/x7f.*/, "")' TAGS | 
wc ­l
1017




     大量のグローバル変数、
     ...
Local static variables
$ grep '^  *static' *.c | wc ­l
39




    ローカルのstatic変数も
Strange code
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *function;
     Keymap map;
...
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *function;
     Keymap map;
{
  int resul...
① save global variable
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *function;
     Ke...
② set argument to global variable
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *functi...
③ call function
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *function;
     Keymap ma...
④ restore global variable
int
rl_bind_key_in_map (key, function, map)
     int key;
     rl_command_func_t *function;
    ...
( ゚д゚)
Make readline-like library
       by Ruby?

   readlineモドキをRubyで
   新しく作る?
ReadRhine
http://github.com/emasaka/ReadRhine
Works only on Ruby 1.9
     (for character handling)



  Ruby 1.9系専用
  (文字の扱いが違うので)
Requires (from gem)

● ruby-termios
● ruby-terminfo
●   “xterm” in terminfo
    (I found it this morning)




             terminfoで“xterm”
             (今朝気付いた)
How to use

 使い方
OOP interface
require 'readrhine'

rr = ReadRhine.new(prompt: '> ')
text = rr.readline




     OOPインターフェイス
readline compatible interface
require 'readrhine/rlcompat'

text = ReadRhine.readline('> ')




    readline互換インターフェイス
Structure

  構造
MVC
Models             Views
                   Display
Buffer
Keymap
History            Controls
Undo               Comma...
Models don't depend on
  Views and Controls

    ModelはViewやControlに
    依存していない
Main loop
                             read
while true
  seq = read_key_seq(@keymap)
  dispatch(seq, @keymap)     eval
  @...
unit test friendly

ユニットテストしやすい
Spec of Buffer
it "should contains inserted string at top" do
  ins_str1 = 'xyz'
  ins_str2 = '123'
  @buffer.insert(ins_s...
Spec of Completion
describe ReadRhine::Completion, "when given completion_proc" 
do
  before do
    @list1 = %w[foobar foo...
Internal DSL

 内部DSL
Key definition
@keymap = Keymap.new
@keymap["C­f"] = :forward_char
@keymap["C­xC­u"] = :undo




            キーの定義
Available commands

  いまあるコマンド
Cursor movement
@@default_keymap["C­a"] = :beginning_of_line
@@default_keymap["C­b"] = :backward_char
@@default_keymap["C­...
Finishing
@@default_keymap["C­j"] = :done
@@default_keymap["C­m"] = :done




            入力終了
Deleting
@@default_keymap["C­d"] = :delete_char
@@default_keymap["C­h"] = :backward_delete_char
@@default_keymap["C­k"] = ...
undo
@@default_keymap["C­_"] = :undo
@@default_keymap["C­xC­u"] = :undo




            アンドゥ
Completion
@@default_keymap["C­i"] = :complete

@@default_keymap["C­i"] = :menu_complete




            補完
History
@@default_keymap["C­n"] = :next_history
@@default_keymap["C­p"] = :previous_history
@@default_keymap["e[A"] = :pre...
TODOs

やんなくちゃならないこと
●   Safe signal handling
●   More about completion
●   History search
●   Per-word cursor movement
●   Digit argument
●   ...
Most confusing is ...

 いちばんややこしいのは…
character width

  文字幅
Width of “☆” is ...

   “☆”の幅は…
Only terminal knows

   そのターミナルだけが
   知っている
Messy

めんどくさい
DEMO

デモ
Upcoming SlideShare
Loading in …5
×

人力

1,095 views

Published on

Published in: Self Improvement
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,095
On SlideShare
0
From Embeds
0
Number of Embeds
126
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

人力

  1. 1. 人力 @emasaka #tqrk02
  2. 2. 入力 @emasaka #tqrk02
  3. 3. Introduce Myself 自己紹介
  4. 4. Occupation 職業
  5. 5. FREE 無職
  6. 6. Period 以上
  7. 7. Main Topic 本題
  8. 8. Termtter
  9. 9. Troubles happens around “Input” 入力まわりはトラブルの巣
  10. 10. And そして
  11. 11. We hopes to extend “Input” by Ruby 入力をRubyで拡張したい
  12. 12. Example: Prompt the number of characters 例:文字数をプロンプトに表示 ※画面は合成です
  13. 13. Example: Auto Complete 例:自動補完 ※画面は合成です
  14. 14. For that purpose そのために
  15. 15. Extend readline by Ruby? readlineをRubyで拡張?
  16. 16. Have to handle... ● C functions ● C variables ● C datas Cの関数、Cの変数、Cのデータ を扱わなくちゃならない
  17. 17. Port readline by Ruby? readlineをRubyに移植?
  18. 18. Many codes $ cat *.[ch] | wc ­l 28955 大量のコード
  19. 19. Many global variables $ ruby ­ne 'next if /#|f|./;  print gsub(/x7f.*/, "")' TAGS |  wc ­l 1017 大量のグローバル変数、 static変数
  20. 20. Local static variables $ grep '^  *static' *.c | wc ­l 39 ローカルのstatic変数も
  21. 21. Strange code int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap;   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } へんなコード
  22. 22. int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap; Differs one argument   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } 引数1個が違う関数
  23. 23. ① save global variable int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap;   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } グローバル変数を保存
  24. 24. ② set argument to global variable int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap;   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } 引数をグローバル変数にセット
  25. 25. ③ call function int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap;   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } 関数呼び出し
  26. 26. ④ restore global variable int rl_bind_key_in_map (key, function, map)      int key;      rl_command_func_t *function;      Keymap map; {   int result;   Keymap oldmap;   oldmap = _rl_keymap;   _rl_keymap = map;   result = rl_bind_key (key, function);   _rl_keymap = oldmap;   return (result); } グローバル変数を復旧
  27. 27. ( ゚д゚)
  28. 28. Make readline-like library by Ruby? readlineモドキをRubyで 新しく作る?
  29. 29. ReadRhine http://github.com/emasaka/ReadRhine
  30. 30. Works only on Ruby 1.9 (for character handling) Ruby 1.9系専用 (文字の扱いが違うので)
  31. 31. Requires (from gem) ● ruby-termios ● ruby-terminfo
  32. 32. ● “xterm” in terminfo (I found it this morning) terminfoで“xterm” (今朝気付いた)
  33. 33. How to use 使い方
  34. 34. OOP interface require 'readrhine' rr = ReadRhine.new(prompt: '> ') text = rr.readline OOPインターフェイス
  35. 35. readline compatible interface require 'readrhine/rlcompat' text = ReadRhine.readline('> ') readline互換インターフェイス
  36. 36. Structure 構造
  37. 37. MVC Models Views Display Buffer Keymap History Controls Undo Command Completion
  38. 38. Models don't depend on Views and Controls ModelはViewやControlに 依存していない
  39. 39. Main loop read while true   seq = read_key_seq(@keymap)   dispatch(seq, @keymap) eval   @display.redisplay end print メインループ
  40. 40. unit test friendly ユニットテストしやすい
  41. 41. Spec of Buffer it "should contains inserted string at top" do   ins_str1 = 'xyz'   ins_str2 = '123'   @buffer.insert(ins_str1)   @buffer.point = 0   @buffer.insert(ins_str2)   @buffer.to_s.should == ins_str2 + ins_str1 end BufferのSpec
  42. 42. Spec of Completion describe ReadRhine::Completion, "when given completion_proc"  do   before do     @list1 = %w[foobar foobaz foohoge]     @buffer = ReadRhine::Buffer.new     @completion = ReadRhine::Completion.new(@buffer)     @completion.completion_proc = ­>(_){@list1}   end   it "should get common string" do     @completion.attempted_completion('').should == 'foo'   end end CompletionのSpec
  43. 43. Internal DSL 内部DSL
  44. 44. Key definition @keymap = Keymap.new @keymap["C­f"] = :forward_char @keymap["C­xC­u"] = :undo キーの定義
  45. 45. Available commands いまあるコマンド
  46. 46. Cursor movement @@default_keymap["C­a"] = :beginning_of_line @@default_keymap["C­b"] = :backward_char @@default_keymap["C­e"] = :end_of_line @@default_keymap["C­f"] = :forward_char @@default_keymap["e[D"] = :backward_char @@default_keymap["e[C"] = :forward_char @@default_keymap["eOH"] = :beginning_of_line @@default_keymap["eOF"] = :end_of_line カーソル移動
  47. 47. Finishing @@default_keymap["C­j"] = :done @@default_keymap["C­m"] = :done 入力終了
  48. 48. Deleting @@default_keymap["C­d"] = :delete_char @@default_keymap["C­h"] = :backward_delete_char @@default_keymap["C­k"] = :kill_line @@default_keymap["C­u"] = :unix_line_discard @@default_keymap["x7f"] = :backward_delete_char 削除
  49. 49. undo @@default_keymap["C­_"] = :undo @@default_keymap["C­xC­u"] = :undo アンドゥ
  50. 50. Completion @@default_keymap["C­i"] = :complete @@default_keymap["C­i"] = :menu_complete 補完
  51. 51. History @@default_keymap["C­n"] = :next_history @@default_keymap["C­p"] = :previous_history @@default_keymap["e[A"] = :previous_history @@default_keymap["e[B"] = :next_history 履歴
  52. 52. TODOs やんなくちゃならないこと
  53. 53. ● Safe signal handling ● More about completion ● History search ● Per-word cursor movement ● Digit argument ● ...
  54. 54. Most confusing is ... いちばんややこしいのは…
  55. 55. character width 文字幅
  56. 56. Width of “☆” is ... “☆”の幅は…
  57. 57. Only terminal knows そのターミナルだけが 知っている
  58. 58. Messy めんどくさい
  59. 59. DEMO デモ

×