2010/07/31

attr_accessor

『プログラミングRuby1.9 言語編』(ISBN: 978-4-274-068096) を読みながら試してみたこと
# P.351 にクラスレベルのアクセサを定義する方法と解説がありました。

class Test
@var = 99
class << self
attr_accessor :var
end
end

puts "Original value = #{Test.var}"
Test.var = "cat"
puts "New value = #{Test.var}"

# 実行結果

Original value = 99
New value = cat


# 少し書き換えself を表示してみると

class Test
  p self
  @var = 99
  class << self
    p self
    attr_accessor :var
  end
end

# 実行結果

Test
#<Class:Test>
Original value = 99
New value = cat


# P.351 には

... 次のように特異クラス内で attr_accessor を呼び出す必要があります。

# とあるのだからして
# <Class:Test> が特異クラスなのだと理解していいのだろうか?
# #<Class:#<MyClass:xxxxx>> のような形式になっていないのが気になる...
# という疑問は一旦おいといて

# で、この class << self を使わないかぎり attr は定義できないのだろうか?
# class << self と書くのとは異なる方法はないのかな?

class Test1
  @var = 89
  self.class.attr_accessor :var
end

実行結果

# =>
./test.rb:30:in `<class:Test1>': private method `attr_accessor' called for Class:Class (NoMethodError)
  from ./test.rb:28:in `<main>'

# エラーだ。
# attr_accessor は <class:Test1> にとって private method だから外から呼べないよと言われてしまった。
# そんなメソッドは知らない、とは言われてない、てことは?

class Test2
  @var = 123
  self.class.send(:attr_accessor, :var)
end

puts "Original value = #{Test2.var}"
Test2.var = "dog"
puts "New value = #{Test2.var}"

# 実行結果

Original value = 123
New value = dog

# やったー
# では、これをinitialize の中でも使えるかな?

class Test3
  def initialize
    @var = "99-dayo"
    self.class.send(:attr_accessor, :var)
  end
end

t = Test3.new
puts "Original value = #{t.var}"
t.var = "apple"
puts "New value = #{t.var}"

# 実行結果

Original value = 99-dayo
New value = apple


# 使えた!ので ...

# @varなど予め定義されたインスタンス変数が不要な場合で(というか用意したハッシュの値を既定値にしたい)
# 尚かつインスタンス変数を定義する時になんら制限をもたせなくてよい条件下。
# ハッシュをうけとった class Test4 が
# 受け取ったハッシュをもとにインスタンス変数とアクセサを定義するには?

class Test4
  def initialize(h)
    @now ||= Time.now
    h.each{|k,v|
      ks = k.downcase.to_sym
      self.class.send(:attr_accessor, ks)
      self.send("#{ks}=", v)
    }
  end
end

h = {"Now"=>"123","Cat"=>"meow", "Dog"=>"bowwow"}
t = Test4.new(h)
p t, t.cat, t.dog

puts "----\n"
print "Instance_variables: #{t.instance_variables}\n"
print "Singleton: #{t.singleton_methods} \n"
print "Singleton_class: #{t.singleton_class}\n"

# 実行結果

#<Test4:0xxxxxx @now="123", @cat="meow", @dog="bowwow">
"meow"
"bowwow"
----
Instance_variables: [:@now, :@cat, :@dog]
Singleton: []
Singleton_class: #<Class:#<Test4:0xxxxxx>>


# あれーTest4 の中に singleton_class が存在しているのはなぜかしら
# self.class してる時点で自動的に特異クラスができあがっているのだろうか。

# 一瞬 object_id 同じなのか!?とぎょっとしたけど
# print "Object_id: #{t.object_id}, #{t.singleton_class.object_id}\n"
# を実行してみたら同じじゃなかった。

+++ memo +++

これ <http://midorex.blogspot.com/2010/05/selfsend2.html> を書いた頃...
ハッシュを受け取ったクラスがインスタンス変数を定義する際、アクセサによる一定の制限があればいいと考えた。
なぜなら Amazon から受け取る値の[全て]が必要ではないだろうと判断したから。

でも、全ての値をinstanceにしてもいっかと考えれば
アクセサによる制限は必要なくなるので上記のように書き換えてもいいのかもしれない..がよくわかっていない...。

<http://github.com/midore/get_item_amzon>

2010/07/06

mdiaryについて

mdiary はメモ帳、日記帳、ToDo管理、Blogに投稿したファイルの管理、本の管理、思いついたことをどんどん書き込んでいくだけの雑記帳 ...etc. いろいろな用途に利用できます。

[特徴]
1, ファイルタイプ
mdiary が管理する全てのファイルはテキストファイルであることを前提としています。

2, ファイル内の表記について
当初、Blogspot.com に投稿する記事を管理したかった為下記のような項目になっています。

1 --date
2 2010/07/04 Sun PM 12:40:52
3 --control
4 yes
5 --category
6 diary
7 --title
8 NewTitle
9 --content

3, 必要なもの
Mac OS X 10.6.x
Ruby 1.9.x

4, その他
自分が作成した文書(テキストファイル)は、常に統一した文書フォーマットを維持し、尚かつ素早く検索閲覧できるようにするにはどうすべきか?mdiary はこういった自問自答に対する1つの答えだったりしています。
あと、Ruby で遊ぶための口実のようなものが欲しかったというのもあります。口実が目的でもあり Ruby で遊ぶのが目的でもあり、そのあたりは曖昧模糊としています。いわゆる趣味で作ったやつなのです。
[mdiayr の使い方]
# 設定方法などはREADME を読んでください。
0) 新しい entry の作成
% diary -a 
を実行するとTerminal.app で新しいWindow が開き vim が起動します。
こんな感じです。


# 設定ファイルを編集すると vim 以外の editor に変えることもできます。
# テキストエディット.app に変更することもできます。(参照:README)

category と content を編集します。
category は,で区切ることができます。
content には test ... と記入。
編集し終えたら editor を終了し exit します。

1) リスト表示
% diary -l
1 [-] [2010/07/03 Sat PM 13:51:10] [NewTitle] (diary,mdiary)
Select [i/e/r]:

entry が1つしかない場合はすぐにオプションを訊ねられます。
entry が複数ある場合は entry 番号を選んだ後にオプション選択となります。
何も選択しないでこのまま終了する場合はリターンキーか CTRL + C で終了します。

i を選択すると entry ファイルのパスや生成時刻、カテゴリーなどをみることができます。
e を選択すると 先ほどと同じように entry ファイルを開きます。
r を選択すると 選択された entry ファイルは ~/.m_diary/trash に移動し2度とリストに現れなくなります。

2) 日時とタイトルを指定して新しい entry を作る場合
% diary -a 'お菓子ストック' -t '2010/07/30 18:00'

-a でタイトルを指定しています。
-a だけを指定し -t がなかった場合は自動的に現在の日付時刻になります。
-t は '2009/12/01 1:00:00' など過去の日付を指定することもできます。秒数もOKです。

control と content を編集します。
お菓子ストックは重要なので control を 「yes」 から 「must」 にしてファイルを保存します。



保存したらexit します。

リストをみます。
% diary -l
1 [+] [2010/07/30 Fri PM 18:00:00] [お菓子ストック] (diary)
2 [-] [2010/07/03 Sat PM 13:51:10] [NewTitle] (diary,mdiary)
Select NO:

controlを yes 「以外」にすると [-] だったところが [+] になります。

3) [+] マークがついた entry の表示
% diary -s +
1 [+] [2010/07/30 Fri PM 18:00:00] [お菓子ストック] (diary)

-s をつけると tilte, category, control を検索し該当する entry を表示します。
-s '7/30'
でも同様の結果を得られます。

お菓子も大事だけど水と缶詰も重要だったことに気づきました。
2つ目のentryを追加します。
% diary -a 水と缶詰のストック -t '2010/07/30 18:00'
2
Same name file is exist.

先ほどと全く同じ時刻を指定しまった為エラーになりました。
時刻を少し変え 18:10 にすると entry を追加できます。
% diary -a 水と缶詰のストック -t '2010/07/30 18:10'

水と缶詰も重要なので
editor でcontrol を 「yes」 から 「must」 に変えておきます。

[+] の entry を検索します。
% diary -s +
1 [+] [2010/07/30 Fri PM 18:10:00] [水と缶詰のストック] (diary)
2 [+] [2010/07/30 Fri PM 18:00:00] [お菓子ストック] (diary)

4) 今日の日付を持つ entry の表示
% ./test.rb -today
1 [-] [2010/07/03 Sat PM 13:51:10] [NewTitle] (diary,mdiary)
です。

5) 検索について
-s をつけると category, title, control, date 内を検索します。
-st をつけると content 内を検索します。
-today は今日の日付のentry を検索します。

6) 予定の entry の追加
来月になったら思い出すべき事柄があったとします。
未来の日時を指定して entry を追加します。
% diary -a 'Watch TV' -t '2010/08/19 23:00'

editor で編集します。
プラスマークを検索した時に表示させたいので control を 「yes」 から 「enjoy」 にしておきます。
category を TV,music にします。
content に .... 要注意! と記入しファイルを保存し editor を終了します。


リストで来月(現在:2010/07/03) のentry をみるためには -d 2010-08 をつけます。
% diary -d 2010-08 -l
1 [+] [2010/08/19 Thu PM 23:00:00] [Watch TV] (TV,music)
Select [i/e/r]:

-d がない限り、今月の entry 「だけ」を表示します。
# ToDo : 今月の entry しかリストにあらわれないのはやっぱり不便かな...と考え中です。
(コンピュータの日付が8月以降になれば  % diary -l  と打つと 2010年08月の日付をもつentry があらわれます。)

7) content の検索
content の内容に'要注意'という単語が含まれているentry を表示します。
% diary -d 2010-08 -st '要注意'
1 [+] [2010/08/19 Thu PM 23:00:00] [Watch TV] (TV,music)
Select [i/e/r]:

検索する時も -d で検索する月を指定します。-d がなければ今月の entry 内だけを検索します。
# 私のmdiary を vim で検索してみたところ
% diary -s vim
1 [-] [2010/07/02 Fri PM 22:57:36] [vim-practice-autocommand] (vim)
2 [-] [2010/07/02 Fri AM 10:00:00] [vim-practice-filetype] (vim)
3 [+] [2010/07/01 Thu PM 23:00:00] [safari.scpt] (vim, SnowLeopard)

めんどい時は最初から grep などを使ってください。# え"

+++ memo +++
実際の放送予定
2010/08/19 Thu PM 23:30:00

2010/07/01

safari.scpt

インターネットでなにかをみていると、これは!と思うことがあります。ふとみれば vim が立ち上がっている。今開いているファイルにこのURL をメモしておきたいと思ったらどうしたらいいんだろ...

昔(OS 9 の頃か?)今みているブラウザのURL とタイトルをクリップボードにコピーするAppleScript をどなたかが公開していた思うのですが、それに近いことを vim 内でできないかな?って試みです。

vim から osascript を呼び出せると最近知りましたので使ってみました。

# home に戻ります。
$ cd
# テキストファイルを作ります。
$ vim 01.txt
# .applescript でも .txt でもどっちでもいいみたい。

$ 01.txt

tell application "Safari"
  tell current tab of window 1
    set str to "-- 
" & name & "
" & URL
  end tell
  return str
end tell


# コンパイルしてみます。# この時 Safari が起動します。(起動していなかった場合)
$ osacompile -o ~/01.scpt 01.txt

$ vim memo.txt
# vim で memo などしています。と思いきやインターネットもみているとします。

# !!と思ったら
:r !osascript ~/01.scpt


--
Apple - Support - Discussions - Forum Home
http://discussions.apple.com/index.jspa


# ↑こんな感じに title とulr が書き込まれます。
# でも
# Safari の window を開いない時に誤って :r! osascript ... したとすると
... Can’t make name of «class cTab» of window 1 of application "Safari" ....
# ↑このようになっちゃいます。これを修正しつつあらたまった風情にしてみます。

$ cat 02.applescript

script get_title_url
  to main()
    set n to ASCII character (10)
    tell application "Safari"
      try
        tell current tab of window 1
          set str to "--" & n & name & n & URL & n & "<a href='" & URL & "'>" & name & "</a>"
          if URL is "" then return
          return str
        end tell
      end try
    end tell
  end main
end script

on run
  tell get_title_url
    return main()
  end tell
end run


$ osacompile -o ~/safari.scpt 02.applescript
# test
:r !osascript ~/safari.scpt


--
Mac OS X clipboard sharing - Vim Tips Wiki
http://vim.wikia.com/wiki/VimTip687
<a href='http://vim.wikia.com/wiki/VimTip687'>Mac OS X clipboard sharing - Vim Tips Wiki</a>


# うまくいきました。
# -- INSERT -- で \safari と打つとタイトルとURL とリンク形式文字列が埋め込まれるようにしてみる?
# inoremap <Leader>safari <ESC>:<C-u>read !osascript ~/safari.scpt<CR>kkkddjjA

osascript から受け取る文字列の行頭には \n が混入されている為(\n--\n になる)受け取った後にvim側で kkkdd とかしてます。osascript 側からこれを制御できればいいけどどうしてもわりませんでした。

+++

もっと他の方法(or 適切なのはこうだよ or coolなのあるよ or ふつうこうだよ or plug-in あるよ)などをご存知の方は教えてくださいませ。どのようなコメントも大歓迎です。

[2010-07-08]
fileencodings=utf-8 以外を設定しているとおかしなことになるかもしれません。 アマゾンの本のトップページをsafariで開き、上記の safari.scpt をvim 経由で動かすと下記のようになります。 こうならない場合は :set fileencodings? あたりをみてみてください。

# アマゾンの本トップページ
--
Amazon.co.jp: 本 (和書) 
http://www.amazon.co.jp/%E6%9C%AC-%E5%92%8C%E6%9B%B8/b/ref=sa_menu_jb0/377-9481435-0601213?ie=UTF8&node=465392
109 
<a href='http://www.amazon.co.jp/%E6%9C%AC-%E5%92%8C%E6%9B%B8/b/ref=sa_menu_jb0/377-9481435-0601213?ie=UTF8&node=465392'>Amazon.co.jp : 本 (和書)</a>

# 日本語の本を一冊選んだ場合
--
Amazon.co.jp: 床下の小人たち (岩波少年文庫): メアリー ノートン, ダイアナ・スタンレー, Mary Norton, 林 容吉: 本
http://www.amazon.co.jp/%E5%BA%8A%E4%B8%8B%E3%81%AE%E5%B0%8F%E4%BA%BA%E3%81%9F%E3%81%A1-%E5%B2%A9%E6%B3%A2%E5%B0%91%E5%B9%B4%E6%96%87%E5%BA%AB-%E3%83%A1%E3%82%A2%E3%83%AA%E3%83%BC-%E3%83%8E%E3%83%BC%E3%83%88%E3%83%B3/dp/4001140624/ref=pd_ts_zgc_b_526266_1/377-9481435-0601213?_encoding=UTF8&s=books&pf_rd_m=AN1VRQENFRJN5&pf_rd_s=right-4&pf_rd_r=0EK1B90C9XBKZFDFK6AT&pf_rd_t=1401&pf_rd_p=95969149&pf_rd_i=3077031496
<a href='http://www.amazon.co.jp/%E5%BA%8A%E4%B8%8B%E3%81%AE%E5%B0%8F%E4%BA%BA%E3%81%9F%E3%81%A1-%E5%B2%A9%E6%B3%A2%E5%B0%91%E5%B9%B4%E6%96%87%E5%BA%AB-%E3%83%A1%E3%82%A2%E3%83%AA%E3%83%BC-%E3%83%8E%E3%83%BC%E3%83%88%E3%83%B3/dp/4001140624/ref=pd_ts_zgc_b_526266_1/377-9481435-0601213?_encoding=UTF8&s=books&pf_rd_m=AN1VRQENFRJN5&pf_rd_s=right-4&pf_rd_r=0EK1B90C9XBKZFDFK6AT&pf_rd_t=1401&pf_rd_p=95969149&pf_rd_i=3077031496'>Amazon.co.jp: 床下の小人たち (岩波少年文庫): メアリー ノートン, ダイアナ・スタンレー, Mary Norton, 林 容吉: 本</a>