59
人力 @emasaka #tqrk02

人力

  • Upload
    emasaka

  • View
    842

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 人力

人力@emasaka

#tqrk02

Page 2: 人力

入力@emasaka

#tqrk02

Page 3: 人力

Introduce Myself

自己紹介

Page 4: 人力

Occupation

職業

Page 5: 人力

FREE無職

Page 6: 人力

Period

以上

Page 7: 人力

Main Topic

本題

Page 8: 人力

Termtter

Page 9: 人力

Troubles happens around “Input”

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

Page 10: 人力

And

そして

Page 11: 人力

We hopes to extend “Input” by Ruby

入力をRubyで拡張したい

Page 12: 人力

Example: Prompt the number of characters

例:文字数をプロンプトに表示

※画面は合成です

Page 13: 人力

Example: Auto Complete

例:自動補完

※画面は合成です

Page 14: 人力

For that purpose

そのために

Page 15: 人力

Extend readline by Ruby?

readlineをRubyで拡張?

Page 16: 人力

Have to handle...

●C functions●C variables●C datas

Cの関数、Cの変数、Cのデータを扱わなくちゃならない

Page 17: 人力

Port readline by Ruby?

readlineをRubyに移植?

Page 18: 人力

Many codes

$ cat *.[ch] | wc ­l28955

大量のコード

Page 19: 人力

Many global variables

$ ruby ­ne 'next if /\#|\f|\./; print gsub(/\x7f.*/, "")' TAGS | wc ­l1017

大量のグローバル変数、 static変数

Page 20: 人力

Local static variables

$ grep '^  *static' *.c | wc ­l39

ローカルのstatic変数も

Page 21: 人力

Strange code

intrl_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);}

へんなコード

Page 22: 人力

intrl_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);}

引数1個が違う関数

Differs one argument

Page 23: 人力

① save global variable

intrl_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);}

グローバル変数を保存

Page 24: 人力

② set argument to global variable

intrl_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);}

引数をグローバル変数にセット

Page 25: 人力

③ call function

intrl_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);}

関数呼び出し

Page 26: 人力

④ restore global variable

intrl_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);}

グローバル変数を復旧

Page 27: 人力

( ゚д゚)

Page 28: 人力

Make readline-like library by Ruby?

readlineモドキをRubyで新しく作る?

Page 29: 人力

ReadRhine

http://github.com/emasaka/ReadRhine

Page 30: 人力

Works only on Ruby 1.9(for character handling)

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

Page 31: 人力

Requires (from gem)

●ruby-termios●ruby-terminfo

Page 32: 人力

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

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

Page 33: 人力

How to use

使い方

Page 34: 人力

OOP interface

require 'readrhine'

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

OOPインターフェイス

Page 35: 人力

readline compatible interface

require 'readrhine/rlcompat'

text = ReadRhine.readline('> ')

readline互換インターフェイス

Page 36: 人力

Structure

構造

Page 37: 人力

MVC

Buffer

Keymap

History

Undo

Completion

Models Views

Display

Command

Controls

Page 38: 人力

Models don't depend on Views and Controls

ModelはViewやControlに依存していない

Page 39: 人力

Main loop

while true  seq = read_key_seq(@keymap)  dispatch(seq, @keymap)  @display.redisplayend

メインループ

read

eval

print

Page 40: 人力

unit test friendly

ユニットテストしやすい

Page 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_str1end

BufferのSpec

Page 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'  endend

CompletionのSpec

Page 43: 人力

Internal DSL

内部DSL

Page 44: 人力

Key definition

@keymap = Keymap.new@keymap["\C­f"] = :forward_char@keymap["\C­x\C­u"] = :undo

キーの定義

Page 45: 人力

Available commands

いまあるコマンド

Page 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

カーソル移動

Page 47: 人力

Finishing

@@default_keymap["\C­j"] = :done@@default_keymap["\C­m"] = :done

入力終了

Page 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

削除

Page 49: 人力

undo

@@default_keymap["\C­_"] = :undo@@default_keymap["\C­x\C­u"] = :undo

アンドゥ

Page 50: 人力

Completion

@@default_keymap["\C­i"] = :complete

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

補完

Page 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

履歴

Page 52: 人力

TODOs

やんなくちゃならないこと

Page 53: 人力

● Safe signal handling● More about completion● History search● Per-word cursor movement● Digit argument● ...

Page 54: 人力

Most confusing is ...

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

Page 55: 人力

character width

文字幅

Page 56: 人力

Width of “☆” is ...

“☆”の幅は…

Page 57: 人力

Only terminal knows

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

Page 58: 人力

Messy

めんどくさい

Page 59: 人力

DEMO

デモ