クエリパラメータを取得するのにCGIクラスを使っています。

Rubyのマニュアルでは『フォームフィールドの値を得る』として以下の様に記載してあります。
require "cgi"
cgi = CGI.new
values = cgi['field_name'] # <== 'field_name' の配列

私が使用しているサーバはWindowsサーバでして、取得したクエリ(フォームフィールド)は文字コードをs-jisに変換して使う事が大半です。

そこで、CGIクラスそのものを改造して、いちいちvalues.tosjisしなくてもよい様にしたいです。

実は以前に、同じような事を質問してまして(http://oshiete1.goo.ne.jp/qa4944090.html)alias を使えばこのようなことが出来るかなと思い、以下の様に書いてみました。(行頭は全角スペースです。)

#!/usr/local/bin/ruby
require 'cgi'
require 'kconv'
STDOUT.binmode
STDIN.binmode
class CGI
 alias :initialize_orig :initialize
 def initialize()
  hash=initialize_orig()
  hash.each do|key,val|
   hash[key]=val.collect{|x|x.tosjis}
  end
  hash
 end
end
cgi=CGI.new
if cgi.has_key?('arg') then
 STDERR.puts cgi['arg']
 cgi.out(){'ok'}
end

結果は
`initialize': undefined method `each' for nil:
NilClass (NoMethodError)
で実行不可でした。
initializeはリターンできないからかな。

次に、
class CGI
 alias :params_orig :params
 def params()
  hash=params_orig
  hash.each do|key,val|
   hash[key]=val.collect{|x|'*' + x + '*'}
  end
 hash
end
end
などとも書いてみましたが、
undefined method `params' for class `CGI'
で実行不可でした。

ご指導のほど、よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

テストしてませんが、これでどうでしょう。


class MyCGI < CGI
 def initialize(type = "query")
  super
  @params = @params.each do|key,val|
   @params[key]=val.collect{|x|x.tosjis}
  end
 end
end
cgi=MyCGI.new
if cgi.has_key?('arg') then
 STDERR.puts cgi['arg']
 cgi.out(){'ok'}
end

あと、tosjisメソッドは入力文字列コード自動判定ですが、短い文字列だと判定が間違う可能性があるので、kconvメソッドで入力文字コードも指定した方がいいです。

この回答への補足

notnotさん ご回答ありがとうございます。
#たびたびのご回答、ありがとうございます。

>def initialize(type = "query")
のtype = "query"の意味がよくわかりませんでしたが、
def initialize()として動かしてみたところ、問題なく動作しました。

ご回答頂いた解法は、CGIクラスそのものを改造というより、CGIクラスを
継承して、新しいクラスMyCGIを作る方法ですが、できればCGIクラスそのものを改造したいです。
もしくは、新しいクラスを生成しないで、特異クラス定義でなんとかならないでしょうか?
cgi=CGI.new
class << cgi
ここをどう書いたらよいか解らない。
end

上手く伝えられないのですが、『cgi=MyCGI.new』と記述する事になぜか
抵抗がありまして。。

良案ありましたら、よろしくお願いいたします。

補足日時:2009/05/19 17:16
    • good
    • 0

>継承して、新しいクラスMyCGIを作る方法ですが、できればCGIクラスそのものを改造したいです。



機能の追加じゃなくて機能を変えることになるので、新規クラスがいいと思いますが。
もとのクラスでやるとすると、cgi.rbの最後の方に書いてあるdef initialize(...) .... end を全部コピーして、その最後の部分に、@paramsの書き換えを追加するのでしょうか。
class CGI
 def initialize(type = "query")
  ここにオリジナルのコードをコピー
  @params = @params.each do|key,val|
   @params[key]=val.collect{|x|x.tosjis}
  end
 end
end

あるいは、paramsメソッドだけ書き換えればいいのであれば、
class CGI
 module QueryExtension
  def params
   w = {}
   @params.each{|k,v| w[k]=v.collect{|x| x.tosjis}}
   w
  end
 end
end
毎回全部をコード変換するので、あまり良くないかな?フラグを設けて、初回だけ@paramsを書き換えるようなほうがいいでしょうね。

いずれにせよ、CGIクラスの機能を変更したい(orサブクラスを作りたい)のならば、cgi.rbを読まないとだめですよ。
    • good
    • 0
この回答へのお礼

notnotさん ご回答、ありがとうございます。
大変勉強になります。

>>機能の追加じゃなくて機能を変えることになるので、新規クラスがいいと思いますが。
先日notnotさんにご回答頂いた【ruby】クラスCGIを改造したい(​http://oshiete1.goo.ne.jp/qa4944090.html​)ですと、aliasを使って
CGIクラスの機能を変えていたので、『あり』なのかと思ってましたが、今回の解法をみますと、一番最初のご回答がスッキリしてるように思います。

>>cgi.rbを読まないとだめですよ。
はい。

お礼日時:2009/05/20 16:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング