【一人 Ruby Advent Calendar 2017】キーワード引数や Hash の渡し方や受け取り方いろいろ【24日目】
一人 Ruby Advent Calendar 2017 24日目の記事になります。
Ruby 3.0 でキーワード引数をぶっ壊すらしいのですが、現状の仕様をよく理解していないので簡単にまとめてみようかと。
Hash を渡す時に {}
を省略
引数の最後が Hash 値の場合、{}
を省略して書くことが出来ます。
def func a, b return a, b end # Hash 値を渡す p func 42, { name: "homu", age: 14 } # =>[42, {:name=>"homu", :age=>14}] # 最後の引数が Hash 値の場合、{} を省略出来る p func 42, name: "homu", age: 14 # =>[42, {:name=>"homu", :age=>14}] # Hash でなくても渡せる p func 42, 32 # =>[42, 32] # 最後でなければエラー # Error:syntax error, unexpected ')', expecting => # p func name: "homu", age: 14, 42
**
で受け取る
メソッドの引数に **
を付けることで『Hash として受け取る』事を明示化することが出来ます。
def func a, **hash return a, hash end # Hash 値を渡す p func 42, { name: "homu", age: 14 } # =>[42, {:name=>"homu", :age=>14}] # 最後の引数が Hash 値の場合、{} を省略出来る p func 42, name: "homu", age: 14 # =>[42, {:name=>"homu", :age=>14}] # Hash でなければエラー # Error: wrong number of arguments (given 2, expected 1) (ArgumentError) p func 42, 32
キーワード引数
以下のように引数を定義する時に『引数名: デフォルト値』と記述することでキーワード引数として定義できる。
キーワード引数はメソッドを呼び出す時に『引数名: 値』のようにして『任意の引数名に対して』引数を渡すことが出来る。
def func id, name: :homu, age: 14 { id: id, name: name, age: age } end p func 1, name: :homu, age: 14 # =>{:id=>1, :name=>:homu, :age=>14} p func 1, age: 15, name: :mami # =>{:id=>1, :name=>:mami, :age=>15}
よくあるのが複数の引数があった場合に『一部の引数だけ渡す』みたいな時に使うことが多いですかねー。
def setting a: 1, b: 2, c: 3 end # 一部の引数だけ渡す setting a: 10 setting b: 20 setting c: 30
まとめ
- Hash をいい感じに渡す手段はいくつかある
- メソッドの受け取り側と渡し側でどのようにして引数を渡すのか意識する必要がある
今まで雰囲気で使っていたんですが、思ったよりも役割によって使う機能が違っている感じですねー。
もっとなんか複雑だと思っていたんですが、言われてみれば『そうかーそうやって使い分けるのかー』という印象。
Ruby 3.0 だとこのあたりをもっとよくするらしいんですが、どうなるんでしょうねえ…。
参照
【一人 vimrc advent calendar 2017】キーマッピングの注意点とか【24日目】
一人 vimrc advent calendar 2017 24日目の記事になります。
今日はクリスマスイヴですね。
ケーキを買いに行ったら売り切れていましたかなしい。
モードごとのキーマッピング
さて、気を取り直して…。
Vim はモードごとに操作が分けられているのはご存知だと思いますが、キーマッピングもモードごとに設定することが出来ます。
代表的なのは以下のようなものになります。
登録コマンド | 削除コマンド | モード |
---|---|---|
:map :noremap |
:unmap |
ノーマル、ビジュアル、選択、オペレータ待機 |
:nmap :nnoremap |
:nunmap |
ノーマル |
:vmap :vnoremap |
:vunmap |
ビジュアル、選択 |
:smap :snoremap |
:sunmap |
選択 |
:xmap :xnoremap |
:xunmap |
ビジュアル |
:omap :onoremap |
:ounmap |
オペレータ待機 |
:map! :noremap! |
:unmap! |
挿入、コマンドライン |
:imap :inoremap |
:iunmap |
挿入 |
:lmap :lnoremap |
:lunmap |
挿入、コマンドライン、Lang-Arg |
:cmap :cnoremap |
:cunmap |
コマンドライン |
いろいろとありますが、基本的には
:nmap
:nnoremap
:vmap
:vnoremap
:imap
:inoremap
:cmap
:cnoremap
の4つを覚えておけばよいです(あとは textobj 系プラグインを使うなら omap
も。
キーマッピング自体の仕方はまあわかってると思うので省略。
map
と noremap
の違い
Vim でキーマッピングをする上で重要なのが map
と noremap
の違いになります。
と、言っても特に難しくはなくて map
は『再マップされ』、noremap
は『再マップされません』。
どういうことかというと例えば、
imap a aa
とした場合、a
を入力した時に aa
を更に展開しようとするので無限ループします。
一方、
inoremap a aa
の場合は aa
は再展開されないので aa
だけが入力されます。
なのでキーマッピングを行う際に『他に設定したキーマッピングの影響を受けない場合は :noremap
』、『他に設定したキーマッピングの影響を受ける場合は :map
』みたいにして使い分ける必要があります。
と、言っても意図的に展開してほしい場合以外は noremap
を使っておくほうが混乱がないと思います。
ただし、プラグインを使用していると例えば、
nmap hoge <Plug>(hoge-plugin-mapping)
みたいに <Plug>(hoge-plugin-mapping)
をキーマッピングすることがあります。
この <Plug>(hoge-plugin-mapping)
というのは『プラグイン側でマッピングされている設定』になります。
" プラグイン内ではこんな感じでキーマッピングされている nnoremap <silent> <Plug>(hoge-plugin-mapping) :<C-u>Hoge<CR>
なので、このような場合は map
でマッピングする必要があります。
まとめ
キーマッピングについてはいろいろと書きたいことはあるんですが、まー基本的には変な縛りを設けないで自分が使いやすいようなキーマッピングをしておくとストレスなく Vim を使うことが出来るのでよいと思います。
Vim に慣れるのではなくて、自分が使いやすい Vim を目指しましょう。
【一人 Ruby Advent Calendar 2017】Ruby で外部ファイルを読み込むメソッドいろいろ【23日目】
一人 Ruby Advent Calendar 2017 23日目の記事になります。
今回は require
などの外部ファイルを読み込むメソッドを簡単にまとめてみます。
Kernel.#require
引数の Ruby のライブラリを読み込みます。
ここでいう Ruby のライブラリとは、
などのファイルを指します。
# Ruby のスクリプロファイルを読み込む require "hoge.rb" # 動的ライブラリを読み込む require "foo.o"
また、拡張子を省略して記述することも出来ます(その場合は *.rb
を優先して両方のファイルを検索します。
# hoge.rb を優先しつつ hoge.o などを読み込む require "hoge"
同じファイルは複数回読み込みません。
ファイルが絶対パスの場合はそのファイルを、相対パスの場合は組み込み変数 $:
から検索し、最初に見つかったファイルを読み込みます。
また、『require
してるファイルのカレントディレクトリ』は検索の対象にならないので『require
しているファイルからの相対パス』で読み込みたい場合は注意してください。
# こんな感じで require しているファイルからの相対パスでファイルは読み込めない require "../hoge/foo"
Kernel.#require_relative
『現在のファイルからの相対パス』で require
します。
以下のような挙動とほぼ同じです。
require File.expand_path({ファイル名}, File.dirname(__FILE__))
『require
しているファイルからの相対パス』のファイルを読み込みたい場合は require
ではなくて require_relative
を使用してください。
Kernel.#load
require
と違い再ロード可能です。
相対パスの場合は『カレントディレクトリ』も含めて検索します。
また、require
は拡張子を省略した場合は自動的に *.rb
などを補完しますが、load
は『拡張子を補完しない』ので拡張子を記述する必要が有ります。
Kernel.#autoload
指定した定数の名前を最初に参照した時に自動で require
を行います。
# この時点ではまだ "hoge" は読み込まれない autoload(:Hoge, "hoge") # 最初に Hoge を参照した時に require("hoge") が実行される p Hoge
まとめ
メソッド名 | 検索対象 | 拡張子 | 再ロード |
---|---|---|---|
require |
$: のパス |
省略化 | されない |
require_relative |
現在のファイルからの相対パス | 省略化 | されない |
require |
$: とカレントディレクトリ |
省略不可 | される |
基本的に『ライブラリを読み込む際は require
』を使い、『相対パスで読み込みたい場合は `require_relative』を使う、みたいな感じで使い分けるとよいと思います。
【一人 vimrc advent calendar 2017】gvimrc について【23日目】
一人 vimrc advent calendar 2017 23日目の記事になります。
そういえば、gvimrc
について書いてなかったので簡単に書いてみようかと。
GUI 版 Vim
GUI 版の Vim を起動するには環境にもよりますが gvim
コマンドを使って起動させる事が出来ます。
これにより端末上ではなくて GUI アプリとして Vim を起動させることが出来ます。
gvimrc
ファイルは vimrc
ファイルと同じように起動時に読み込まれる設定ファイルですが、GUI 版の Vim を起動した時に『vimrc
の後』に読み込まれます。
読み込まれる gvimrc
ファイルは基本的に vimrc
ファイルと同じですが、起動オプション -U {gvimrc}
や $MYGVIMRC
で指定することが出来ます。
ユーザーの個人的なGUI初期化ファイルを置くのに推奨される場所: Unix $HOME/.gvimrc、$HOME/.vim/gvimrc OS/2 $HOME/.gvimrc、$HOME/vimfiles/gvimrc、$VIM/.gvimrc MS-DOSとWin32 $HOME/_gvimrc、$HOME/vimfiles/gvimrc、$VIM/_gvimrc Amiga s:.gvimrc、home:.gvimrc、home:vimfiles:gvimrc、 $VIM/.gvimrc
gvimrc
で設定するべきオプション
当たり前ですが基本的には GUI 版 Vim でのみ有効にしたい設定を記述します。
また、GUI 版だけで意味のあるオプションもあるので、GUI 版の Vim を使う場合は調べてみるとよいと思います。
オプション | 内容 |
---|---|
'guicursor' |
カーソルの外観を指定 |
'guifont' |
GUI フォントの設定 |
'guipty' |
shell で pseudo-tty を使用するかどうかの設定 |
'guioptions' |
メニューやスクロールバーなど GUI 固有の設定 |
ちなみにこれらのオプションは vimrc
で設定しておいても問題ないです(GUI 版でのみ有効になる。
まとめ
gvimrc
は GUI 版で読み込まれる設定ファイルvimrc
のあとにgvimrc
が読み込まれるgvimrc
固有の設定もある
【一人 vimrc advent calendar 2017】タブページを操作するキーマッピングいろいろ【22日目】
一人 vimrc advent calendar 2017 22日目の記事になります。
もうすぐ Advent Calendar も終わりですね…。
タブページを操作するキーマッピングいろいろ
さて、わたしは基本的にタブページごとにファイルを開いているのですが、そのタブページを扱うキーマッピングをいろいろと紹介してみます。
" タブの移動 nnoremap <silent> <C-l> :tabnext<CR> nnoremap <silent> <C-h> :tabprevious<CR> nnoremap <silent> <C-Tab> :tabnext<CR> " タブページ自体を左右に移動させる command! -bar TabMoveNext :execute "tabmove " tabpagenr() % tabpagenr("$") + (tabpagenr("$") == tabpagenr() ? 0 : 1) command! -bar TabMovePrev :execute "tabmove" (tabpagenr() + tabpagenr("$") - 2) % tabpagenr("$") + (tabpagenr() == 1 ? 1 : 0) nnoremap <silent> <S-l> :TabMoveNext<CR> nnoremap <silent> <S-h> :TabMovePrev<CR>
上記のようなキーマッピングを行うことで素早くタブページを移動したりタブページのレイアウトを変更したり出来ます。
おまけ
:help setting-guitablabel
にも書かれているんですが、以下のように 'guitablabel'
を設定しておくと更にタブページが見やすくなります。
function GuiTabLabel() let label = '' let bufnrlist = tabpagebuflist(v:lnum) " このタブページに変更のあるバッファがるときには '+' を追加する for bufnr in bufnrlist if getbufvar(bufnr, "&modified") let label = '+' break endif endfor " ウィンドウが複数あるときにはその数を追加する let wincount = tabpagewinnr(v:lnum, '$') if wincount > 1 let label .= wincount endif if label != '' let label .= ' ' endif " バッファ名を追加する return label . bufname(bufnrlist[tabpagewinnr(v:lnum) - 1]) endfunction set guitablabel=%{GuiTabLabel()}
タブページを使うと視覚的にもわかりやすいのでバッファがよくわからんという人は使ってみるとよいと思います。
【一人 Ruby Advent Calendar 2017】Ruby の % 記法【22日目】
一人 Ruby Advent Calendar 2017 22日目の記事になります。
そろそろラストスパート
% 記法
Ruby には %
記法という特別なリテラルがあります。
例えば、%w
という記法を使うと以下のように『空白文字で分割した』文字列の配列として定義されます。
p %w(homu mami mado) # => ["homu", "mami", "mado"]
またこの時に記述した %w()
の ()
は []
、{}
、<>
みたいな括弧や『改行を含めた任意の非英数字』を利用することが出来ます。
p %w<homu () mado> # => ["homu", "()", "mado"] p %w`'() [] {}` # => ["'()", "[]", "{}"] p %w!` " '! # => ["`", "\"", "'"]
こんな感じでリテラルで定義する記号によって ()
の記号を変えることが出来ます。
%
、%Q
:ダブルクオート文字列
%
、%Q
は『ダブルクオート文字列』として定義されます。
p %(homu "mami") # => "homu \"mami\"" # 式展開も行える p %Q("#{5 + 4}:mado") # => "\"9:mado\""
%q
:シングルクオート文字列
%q
は『シングルクオート文字列』として定義されます。
p %q(homu "mami" 'mado') # => "homu \"mami\" 'mado'" # 式展開は行われない p %q(#{2 + 4}) # => "\#{2 + 4}"
%x
:コマンド出力
%x
は外部コマンドを実行して結果を返します。
p %x(ls) # => ls コマンドの実行結果
` と同じです。
%r
:正規表現
p %r(\d+) # => /\d+/ # / もエスケープされる p %r(http://.*) # => /http:\/\/.*/
%w
:空白文字で区切った要素が文字列の配列を定義
%w
は『空白文字で区切った要素が文字列の配列』を定義します。
p %w(homu mami mado) # => ["homu", "mami", "mado"] p %w("homu" "ma mi" "mado") # => ["\"homu\"", "\"ma", "mi\"", "\"mado\""]
%W
:%w
と同等(式展開とバックスラッシュ記法が有効)
%w
と同等ですが『式展開とバックスラッシュ記法』が有効です。
p %W(#{2 + 4}:#{[1, 2, 3]}) # => ["6:[1, 2, 3]"] p %W(homu ma\mi mado) # => ["homu", "mami", "mado"]
%s
:シンボル
%s
は『シンボル』で定義されます。
また、式展開、バックスラッシュ記法は無効です。
p %s(homu) # => :homu p %s(42) # => :"42" p %s(#{1 + 2}) # => :"\#{1 + 2}"
%i
:空白文字で区切った要素がシンボルの配列を定義
%i
は %w
と同様に『空白文字で区切った要素』の配列として定義されますが、文字列ではなくてシンボルとして定義されます。
p %i(homu mami mado) # => [:homu, :mami, :mado] p %i(homu mami #{2 + 2}) # => [:homu, :mami, :"\#{2", :+, :"2}"
%I
:%i
と同等(式展開とバックスラッシュ記法が有効)
%i
と同等ですが、『式展開とバックスラッシュ記法』が有効になります。
p %I(homu mami mado) # => [:homu, :mami, :mado] p %I(homu mami #{2 + 2}) # => [:homu, :mami, :"4"]
まとめ
正規表現で /
を含めいたことは稀によくあるのでそういう場合は %r
を使うと楽ですねえ。
参照
【一人 vimrc advent calendar 2017】コマンドを実行した際にカーソル位置を移動させないスクリプト【21日目】
一人 vimrc advent calendar 2017 21日目の記事になります。
そろそろネタが枯渇してきているのですが、今日 vimrc
から便利そうなスクリプトを発掘したのでそれの初回でも。
カーソル位置などを移動させないでコマンドを実行するスクリプト
元々、他の方の vimrc
に書かれていたスクリプトになります。
" 元ネタ " https://github.com/bling/dotvim/blob/d84e501bd12f9c6887599ace398fe26f542e8f6e/vimrc#L105 function! s:preserve(command) "{{{ " preparation: save last search, and cursor position. let _s=@/ let view = winsaveview() " do the business: execute a:command " clean up: restore previous search history, and cursor position let @/=_s call winrestview(view) endfunction "}}} command! -complete=command -nargs=* \ Preserve call s:preserve(<q-args>)
上記のスクリプトを使うことで例えば :substitute
した時などに『カーソル位置を移動させずに』置換を行うことが出来ます。
:Preserve %s/\s\+$//g
また、以下のようなコマンドを定義しておくと :Preserve %s
を :S
として使えるようになります。
command! -complete=command -range -nargs=* \ S Preserve %s <args>
今までほとんど使ったことがなかったんですが普通に便利そう…。