生の方が良いけど。
MacBookが壊れたのはあれだ、すっかり馴染んでしまい、あまり気にかけてやらなかったせいで、倦怠期のカップルの女が妙に怒りっぽくなったりするのと同じだ、ということで久しぶりのプレゼントとしてiSkinなる「アメリカ製の多色展開しているコンドームみたいな名前だな」と思ってしまったキーボードカバーをこちらで購入。
パッケージが格好良いです。
早速、装着。
US配列専用です。
この手のキーボードカバー、何回か使ったことがあるのですが、やはりヘニャヘチャ感は否めません。意外と気に入っていたMacBook特有のカチャカチャとしたキータッチがすっかり陰を潜めています。
また、キーが若干高くなることで今のところ、ミスタッチが多くなっています。
それでも「もう、イヤー」というほどイヤではないので、もうしばらく使ってみようと思います。
昔はキータッチにこだわり『Thinkpad大好きっ子』だったのですが、その辺のこだわりはすっかりなくなってしまった今日この頃です。年齢を重ね「俺も丸くなったな」という感じです。
はてなブックマークに一括登録。
先ほどのスクリプトで誤って削除してしまったのを復元するため、涙を拭いながら急いで作成。
お勉強よりも作業速度短縮を優先でHatenaBMモジュールを使用しています。
HatenaBMモジュールはRubyGemsからインストール可能です。
gem install hatenabm
ファイルから読み込んだURLにrubyというタグをつけ、タイトルはこちらによると編集できないようなので、空文字を渡して登録します。
require 'rubygems' require 'hatenabm' require 'uri' hbm = HatenaBM.new( :user => 'username', :pass => 'password' ) File.open('url.txt') do |file| file.each do |line| next unless URI.split(line).first == 'http' rescue false ret = hbm.post( :title => '', :link => line, :tags => 'ruby' ) print("#{ret.to_s}:#{line}") end end
読み取った文字列がURLかどうかの判定を
next unless URI.split(line).first == 'http' rescue false
このように行っていますが、こちらを参考にさせていただきました。
はてなブックマークから指定されたタグのエントリを削除する。
こちらを参考に作成。
require 'net/http' require 'digest/sha1' require 'rexml/document' require 'time' $kcode = 'u' Net::HTTP.version_1_2 def x_wsse(username, password) nonce = Array.new(10){ rand(0x100000000) }.pack('I*') created = Time.new.utc.iso8601 digest = Digest::SHA1.digest(nonce + created + password) wsse = "UsernameToken Username=#{username}, ", "PasswordDigest=#{[digest].pack('m').chomp}, ", "Nonce=#{[nonce].pack('m').chomp}, ", "Created=#{created}" { 'x-wsse' => wsse.to_s } end user = 'username' # はてなのユーザ名 pass = 'password' # はてなのパスワード tag = 'tag' # 処理対象のタグ entries = {} Net::HTTP.start('b.hatena.ne.jp') do |http| has_next = true start = 0 # 認証ヘッダ取得 header = x_wsse(user, pass) while has_next response = http.get( "/atom/feed?tag=#{tag}&of=#{start}", header ) doc = REXML::Document.new(response.body) open('doc.xml', 'w') { |f| f.puts(doc.to_s)} # 一度に取得できる件数を取得(tagで検索するとページングする) per_page_elem = doc.elements['/feed/openSearch:itemsPerPage'] if per_page_elem items_par_page = per_page_elem.text.to_i end # エントリのIDとURLを取得 doc.each_element('/feed/entry') do |entry| id = entry.elements['id'].text.scan(/\A.*-([0-9]+)\Z/).to_s url = entry.elements['link[@rel="related"]'].attributes['href'] entries[id] = url end # 次ページがあるかどうかを判定 has_next = doc.elements['feed/link[@rel="next"]'] ? true : false if has_next start += items_par_page end end # 削除するエントリをバックアップ File.open('backup.txt', 'w') do |file| entries.each_value do |url| file.puts(url) puts url end end # エントリを削除 entries.each_key do |id| http.delete("/atom/edit/#{id}", header) end end
2つのファイルの差分を取得。
print File.read(ARGV[0]).to_a - File.read(ARGV[1]).to_a
コマンドライン引数にファイル名を設定する。
RubyGemsでインストール可能なモジュールを検索。
RubyGemsからリモートでインストール可能なモジュールを検索するには、http://docs.rubygems.org/read/chapter/に
gem q -R -n module_name
とするとあるけど、動かない。
面倒だけ仕方がないので、
gem q --remote -n module_name
としていた。
さっき気がついたけど、
gem q -r -n module_name
とすると動く。
今まで、少しだけ時間を無駄にしてたようで悔しい。
価格.comのAPIを使って検索するモジュール。
すでに作られている方がいるけど、お勉強のために自分の今現在持っている知識で書いた。
require 'open-uri' require 'rexml/document' module KakakuAPI BASE_URL = 'http://api.kakaku.com/Ver1/ItemSearch.asp' class KakakuItem include Comparable attr_reader:product_id attr_reader:product_name attr_reader:maker_name attr_reader:category_name attr_reader:pv_ranking attr_reader:image_url attr_reader:item_page_url attr_reader:bbs_page_url attr_reader:review_page_url attr_reader:lowest_price attr_reader:num_of_bbs def initialize(result) @product_id = result.elements['ProductID'].get_text @product_name = result.elements['ProductName'].get_text @maker_name = result.elements['MakerName'].get_text @category_name = result.elements['CategoryName'].get_text @pv_ranking = result.elements['PvRanking'].get_text @image_url = result.elements['ImageUrl'].get_text @item_page_url = result.elements['ItemPageUrl'].get_text @bbs_page_url = result.elements['BbsPageUrl'].get_text @review_page_url = result.elements['ReviewPageUrl'].get_text @lowest_price = result.elements['LowestPrice'].get_text @num_of_bbs = result.elements['NumOfBbs'].get_text end def <=>(rakuten_item) return self.product_id <=> rakuten_item.product_id end end class KakakuItems < Array attr_accessor:num_of_result end class ItemNotFoundError < Exception; end; class TooManyItemRequestedError < Exception; end; class InvalidParameterValueError < Exception; end; class InternalServerErrorError < Exception; end; def self.search(keyword, options = nil) param = self.create_param(keyword, options) url = URI.escape("#{BASE_URL}?#{param}") kakaku_items = KakakuItems.new open(url) do |result| product_info = REXML::Document.new(result.read).root # エラー発生 if product_info.name == 'Error' message = product_info.elements['Message'].get_text.to_s message.strip! case message when 'InvalidParameterValue' raise(InvalidParameterValueError.new) when 'TooManyItemsRequested' raise(TooManyItemsRequestedError.new) when 'ItemNotFound' raise(ItemNotFoundError.new) when 'InternalServerError' raise(InternalServerError.new) else raise('aaa') end end num_of_result = product_info.elements['NumOfResult'].get_text kakaku_items.num_of_result = num_of_result product_info.each_element('Item') do |elem| kakaku_item = KakakuItem.new(elem) kakaku_items << kakaku_item end end return kakaku_items end private def self.create_param(keyword, options = nil) if keyword == nil or keyword.empty? raise(ArgumentError.new('keyword')) end param = "" param << "Keyword=#{keyword}" unless options[:category_group] == nil param << "&CategoryGroup=#{options[:category_group]}" end unless options[:sort_order] == nil param << "&SortOrder=#{options[:sort_order]}" end unless options[:page_num] == nil param << "&PageNum=#{options[:page_num]}" end return param end end
使ってみる。
items = KakakuAPI.search("MacBook", {:category_group => 'Pc'}) items.each do |item| puts item.product_name end
結果。
MacBook 2000/13.3 MA700J/A MacBook 2000/13.3 MA701J/A MacBook 1830/13.3 MA254J/A MacBook Pro 2330/15.4 MA610J/A MacBook Pro 2160/15.4 MA609J/A
let式。
特定の定義のみで有効な束縛ができる。
main = print $ letTest1 5 letTest1 n = let x = n + 1 y = n + 2 z = n + 3 in x * y * z
where節と似ているけど、以下の2点が違う。
- letは式なのでlet自体にも値を持つ、whereは節なので値を持たない
- whereは複数のガードにまたがって有効
使い分けとしては、letの場合は新しい変数を導入するため、whereは関数内で新しい関数を定義するのが一般的。
let式、where節の中で関数の引数と同じ名前の引数を使用した場合
main = print $ letTest1 20 10 letTest1 x y = let y = x * x in y - 1
20 × 20 - 1で結果は、
399
つまり、let式内の変数が使用される。このことをシャドウィング(shadowing)という。
let式内で変数を相互に参照することもできる。
main = print $ letTest letTest = let x = 5 y = x + 2 in x * y
結果。
35
上から参照、下から参照のどちらでも問題ない。
main = print $ letTest letTest = let y = x + 2 x = 5 in x * y
結果は同じになる。
パターンでの束縛も可能。
main = print $ letTest letTest = let(x:xs) = [1,2,3] in xs
結果。
[2,3]
ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門
- 作者: 青木峰郎,山下伸夫
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/06/01
- メディア: 単行本
- 購入: 25人 クリック: 314回
- この商品を含むブログ (320件) を見る