POIで名前定義されているセルを取得する話

環境
  • org.apache.poi 3.7
    • maven repositoryを検索するときは、group id「org.apache.poi」で検索する。
    • group idが「poi」のものはversionが3.1まで。
ソース
  • 複数の時は以下のような感じで
final Name name = workbook.getName("名前");
final AreaReference areaReference = new AreaReference(name.getRefersToFormula());
final CellReference firstCell = areaReference.getFirstCell();
final CellReference lastCell = areaReference.getLastCell();
  • RangeAddressクラスがどっかのversionで消えてしまっていて困っていたんだけど、AreaReferenceを使えば解決!

-

HowToEnsureValidAttributesInFormData


attr_accessibleと可変長引数の話


http://wiki.rubyonrails.org/rails/pages/HowToEnsureValidAttributesInFormData
ちょっと記事が古いなぁ。今なら違う方法でできるかも。

# @params['user'] contains the attributes we want to add

# allowed_attr specifies which attributes are allowed
if some_flag
  allowed_attr = ['name','email','password','status','balance']
else
  allowed_attr = ['name','email','password']
end

# use delete_if so the hash only contains valid attributes
@params['user'].delete_if {|k,v| not allowed_attr.include? k}

# mass assign our cleaned attributes to the object
user = User.new(@params['user'])


active_supportの力があれば!!1

# @params['user'] contains the attributes we want to add

# allowed_attr specifies which attributes are allowed
if some_flag
  allowed_attr = ['name','email','password','status','balance']
else
  allowed_attr = ['name','email','password']
end

# mass assign our cleaned attributes to the object
user = User.new(@params['user'].slice(*allowed_attr)) #←ここに注目
              • -

ぼくも早く2.2に上げて
Object#present?でびゅーしてunlessからおさらばしたいです。
unless 〜 else とか分かりにくいからやめてほしいよ><

private!

privateの意味は、メソッドを関数形式でだけ呼び出せるようにし、レシーバー形式では呼び出せないようにするという意味です。したがって、可視性がprivateなメソッドは、自クラス及びサブクラスからしか参照できません。

protectedも同様に、自クラス及びサブクラスからしか参照できませんが、関数形式でもレシーバー形式でも呼び出せます。

メソッドのカプセル化に必要な機能です。

プログラミング言語 Ruby リファレンスマニュアル

なん…だと…。 こんな基本的なことに今まで気づかなかったとは><


というわけでid:koumiya氏に教えていただいた通り、アクションをまるごとトランザクションにぶち込むのは以下で可能でした。

def perform_action_without_rescue_with_tx
  ActiveRecord::Base.transaction do
    perform_action_without_rescue_without_tx
  end
end
alias_method_chain :perform_action_without_rescue, :tx

create後にraiseしてロールバックされてることも確認しました。 やっほい。

perform_action!

論文なんかよりコードが書きたい!と思ってたらこれができた。


追記2:
private! - kelkronsoの日記


追記:
とおもったらだめだった

こいつでしっかりキャッチされてた><

      def perform_action_with_rescue #:nodoc:
        perform_action_without_rescue
      rescue Exception => exception
        rescue_action_with_handler(exception) || rescue_action(exception)
      end
class ApplicationController < ActionController::Base
 
  def perform_action_with_tx
    puts "before tx"
    ActiveRecord::Base.transaction do
      perform_action_without_tx
    end
    puts "after tx"
  end
  alias_method_chain :perform_action, :tx
end

class Controller << App///

  before_filter do 
    puts "before filter"
  end
  
  after_filter do
    puts "afiter filter"
  end
  
  def index
    
    puts "index in action"
  end

end

れっつあくせす!

before tx
before filter
index in action
afiter filter
after tx

まぁ囲んだだけなんだけどね…

Rubyっぽいコードを書く

#hogeがnilじゃなかったらfugaに代入する

#rubyはじめて30分位の人が書きそうなコード
if hoge != nil
fuga = hoge
end

#nil?くらいは使いたい
if !hoge.nil?
fuga = hoge
end

#!(否定)を使わない
unless hoge.nil?
fuga = hoge
end

#nilはfalseである
if hoge
fuga = hoge
end

#1行で書けるときは1行で
fuga = hoge if hoge
#hogeがnilじゃなかったらfugaに代入する、nilの場合はdefalutを代入する
fuga = []
if hoge
  fuga = hoge
else
  fuga = default_array#default的な何か
end

#ifはブロックを作らない
if hoge
  fuga = hoge
else
  fuga = default_array
end

fuga.each{...} #これはぬるぽにならない

#評価式をうまく
fuga = hoge || default_array
          • -

まったく関係ないけど、injectってresultをちゃんと返してやらないと駄目なんだね><
resultはなぜか知らないけどもっと広いスコープなのかと思ってました。

つまりこんなコードを書いて頭をうならせていたぼくはunkってことです

a = [1,2,3,4,5]
a.inject(0){|result, i| result += i if i>3 } #nilが+できないうぇうぇと言われる

a.inject(0) do |result, i|
  result += i if i>3
  result #resultを毎回返してやればok
end

named_scopeで検索

参考
#112 Anonymous Scopes - RailsCasts

class Product < ActiveRecord::Base
  has_many :product_details
  
  named_scope :active, :conditions => {:enabled => true}
  named_scope :not_deleted, :conditions => {:delete_flg => false}
  named_scope :deleted, :conditions => {:delete_flg => true}
  named_scope :titled, lambda{|query| { :conditions =>["title like ?", "%#{query}%"] }}
  
  def self.search(form)
    
    scope = Product.scoped({})
    scope = scope.active if form[:enabled]
    scope = scope.deleted if form[:deleted]
    scope = scope.titled(form[:query]) unless form[:query].blank?
    scope
  end
end



<% form_tag '/products/search' do%>
  <p>削除 <%= check_box_tag :deleted, 1, @deleted%></p>
  <p>有効 <%= check_box_tag :enabled, 1, @enabled%></p>
  <p>クエリ <%= text_field_tag :query, @query%></p>
  <%= submit_tag :submit  %>
<%end%>


それっぽいSQLは発行されてる、が
scoped({})の部分が何やってるのかわからない〜。

ローカル変数とかスコープとかメソッドとか

ローカル変数と等号付きメソッド

レシーバを省略するとメソッドではなくローカル変数として扱われます。普通のメソッドはselfのレシーバを省略できますが、この場合は不可。

プログラミング言語 Ruby リファレンスマニュアル
class Foo
   def bar=(v)
   end
   def baz
      bar = 0           # ローカル変数 bar への代入
      self.bar = 0      # メソッド bar= の呼び出し
   end
end

今日初めて知りましたスイマセン…。

どこら辺で効いてくるかといえばARの辺りだと思う

class MyVideo < ActiveRecord::Base
  def set_title_aa
    title = "aa" #ただローカル変数に代入してるだけ
  end
  
  def set_title_aaa
    self.title = "aaa" #メソッドを呼び出してる
  end

  def get_title
    title #メソッドを呼び出してる
  end
end
-----
    video = MyVideo.new
    video.title = "testtest"
    puts video.get_title #=>"testtest"
    video.set_title_aa
    puts video.title #=>"testtest"
    video.set_title_aaa
    puts video.title #=>"aaa"

method_missing様様ですね。

制御構造(ifやwhileなど)はスコープを作らない。

while や for がスコープを作らないのに対し、loop や each などのイテレータはスコープを作ります。

プログラミング言語 Ruby リファレンスマニュアル

これも今日知った…。

for i in 1..3
  var = true
end
p var
# => true

これはjavaとかやってる人間からしたら気持ち悪いよなぁ。
ちなみに p iとかやると"3"って出てくる。



最後に

puts puts

これなんて出力されるかわかります?

#改行
nil

と出力されるわけなんですが
右側のputsで空白の改行を出力して、その戻り値のnilを左のputsで出力してる。
という認識なんですが合ってますよね?(笑



ちなみに何でこんな話が出てきたかというと

p = "aiue"
p p

こんなコードを後輩が書いてたからです。
それにしても何でpという変数名を選んだんだろう(笑