機略戦記

Maneuver warfare

MacでRを実行している時、処理が終わったら通知を行う方法

結論

# 処理
system("osascript -e 'display notification \"done.\"'")

結果

f:id:Shinya_131:20151104214013p:plain

説明

  • AppleScriptから通知を行う事ができる。
  • osascriptを使うことで、AppleScriptのコードをシェルからevalできる ← これでshellから通知を行える
  • sysytem()を使うことで、shellのコードをRからevalできる。

関連

shinya131-note.hatenablog.jp

R6でAll elements of public, private, and active must be namedと言われた時チェックすべき点

R6パッケージを使って作ったクラスについて、以下のエラーが出る事がある。

 R6::R6Class("XxxxXxxx", public = list(initialize = function(xxxxx) { でエラー: 
  All elements of public, private, and active must be named. 

R6で定義しているメソッドについて

  • mehotd_name = function() {}では無く、
  • mehotd_name <- function() {}を使うとこのようなエラーが起きるようだ。
XxxxXxxx <- R6::R6Class('XxxxXxxx',
  public = list(
    initialize = function(xxx) {
    },
    hoge <- function(xxx) { # ここで起きてる。
    }
  ),
  private = list(
    xxx = NA
  )
)

rubyでcall stack参照するメソッドがなんだっけ

結論

callerだった。

使用例:

$ pry
[1] pry(main)> caller
=> ["/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:355:in `eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:355:in `evaluate_ruby'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:323:in `handle_line'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `catch'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `block in eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `catch'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:77:in `block in repl'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `loop'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `repl'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `block in start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:61:in `call'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:61:in `__with_ownership'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:79:in `with_ownership'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:15:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_class.rb:169:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:219:in `block in <top (required)>'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `call'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `block in parse_options'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `each'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `parse_options'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/bin/pry:16:in `<top (required)>'",
 "/Users/hoge/.rbenv/versions/2.2.3/bin/pry:23:in `load'",
 "/Users/hoge/.rbenv/versions/2.2.3/bin/pry:23:in `<main>'"]

よもやま

ところでcallerって、メソッドだっけ? それとも特殊な変数か何か? というのが気になった。
このような疑問が湧いた時、defined?を使うと、コンソール上でこれを確認できる。

[9] pry(main)> defined? caller
=> "method"

ところでところで、defined?には調べたいもののシンボルや文字列では無く、調べたい物を直接渡す。

[11] pry(main)> defined? caller
=> "method"

おなじくメタ情報を取得する#methodの場合は、シンボルで引数として受け取ってる。

[13] pry(main)> method(:caller)
=> #<Method: Object(Kernel)#caller>

defined?はなんで構文上意味がある物を直接受け取る事ができるんだろう。
defined?はメソッドなんだろうか?
defined? defined?としてみたが syntax errorになってしまった。

すくなくともメソッドでは無い。

method(:defined?)
NameError: undefined method `defined?' for class `Object'
from (pry):17:in `method'

Rで、指定したdata.tableの全てのカラム名にprefixを付けたい。

結論

table <- data.table(a=1,b=2,c=3)
prefix <- 'hoge'

old_names <- names(table)
new_names <- paste(prefix, old_names, sep='.')

setnames(table, old_names, new_names)

これで、 処理前にnames(table) #=> "a" "b" "c"だったカラム名が、 names(table) #=> "hoge.a" "hoge.b" "hoge.c"になる。

感想

ループもイテレーターも使わずに色々できるの楽しい。

RのR6パッケージを使ってクラスを作るとき、クラスメソッドとかスタティックメソッドみたいな物を定義したい。

背景

R6パッケージで作ったこんなクラスに対して、クラスメソッドとかスタティックメソッドみたいな物を付けたい。 クラスメソッドとスタティックメソッドは違うものだけど、とにかくクラスをインスタンス化しなくても使えるメソッドを付けたい。

# ある証券の値動き。日足。
Stock <- R6::R6Class('Stock',
  public = list(
    initialize = function(price_moves) {
      private$price_moves <- price_moves

      private$convert_value_type()
    },
    # ... public method達
  ),
  private = list(
    # ... private method達
  )
)

用途としては、このStockクラスのinstanceを生成するメソッドをクラスメソッドとして付けたい。

結論

Stock <- R6::R6Class('Stock',
  public = list(
    initialize = function(price_moves) {
      private$price_moves <- price_moves

      private$convert_value_type()
    },
    # ... public method達
  ),
  private = list(
    # ... private method達
  )
)

# オラァ
Stock$create <- function(filepath) {
  Stock$new(fread(paste(work_dir, filepath, sep='')))
}