Ruby Mechanize wiki (ja) - Mechanize::Form::Field

Mechanize::Form::Field


テキスト入力フィールド全般、あるいは hidden なコントロールひとつを表します。
一行入力欄、
<form name="field1">
  <input type="text" name="oneliner" value="">
</form>
複数行の入力欄、
<form name="field1">
  <textarea name="multi">テキスト1行目
2行目</textarea>
</form>
type="hidden" で表現される隠しコントロール、
<form name="field1">
  <input type="hidden" name="subvalue" value="不可視1">
</form>
を、表現します。

Mechanize のページ中の Mechanize::Form#fields に格納されており、Mechanize::Form#field_withMechanize::Form#fields_with で選択・抽出します。
#name で入力欄の name 属性の値を返します。#value= を使用すると入力値を指定(上書き)することができます(通常の Web ブラウザでキーボード入力することに相当します)。
# name が oneliner な入力欄の value に 'Ruby' と指定する
# 送信データは oneliner=Ruby になるはず
agent.page.form_with(:name => 'f1'){|form|
  form.field_with(:name => 'oneliner').value = 'Ruby'
}
value は必ず UTF-8 で指定してください。フォームのあるページの Mechanize::Page#encoding の文字エンコーディングに変換されて送信されます。
なお、実用上「name で探して value= で指定」が余りにも頻繁なため、Mechanize::Form#[]= を使用して
form.field_with(:name => 'oneliner').value = 'Ruby'

form['oneliner'] = 'Ruby'
と書くことが多いです。

実際は入力欄の種類によってこの Field クラスを継承した別の名称のクラスが使用されているのですが、現状名前が違うだけで個々のクラスとして動作が違うわけではないので、とりあえずここで解説します。 <textarea> は Textarea クラスではなくこの Field クラスです。type="text" でも type="textarea" でもないテキスト入力欄、type="password" なものとかもすべてこの Field クラスです。
また、このクラスはフォーム部品すべて(Mechanize::Form::Optionを除く)の継承元クラスとしても使用されているので、いくつかのメソッドはそちらのクラスでも使用されていたりします。これは継承先のクラス説明で適当に説明したり誘導したりしてます。



Mechanize::Form::Field オブジェクトを生成します。ユーザーが使用することはありません。

この入力欄の名前を文字列で返します。
デフォルトはこの入力欄の元となった input 要素 の name 属性の値です。HTML の文字参照は Mechanize::Util.html_unescape されています。nil を返すオブジェクトが作られることはありません(通常の Mechanize::Page#fields 由来の Field の場合)。これは継承先クラスでも同じです(例外は Mechanize::Form::Button)。
<input type="text" name="oneliner" value="1行テキスト">
という HTML で表される入力欄オブジェクトだった場合、name メソッドは oneliner を返します。

この入力欄オブジェクトを作成したときに使用した HTML ノードオブジェクトを返します。
デフォルトでは Mechanize::Form::Field.new の引数で指定されたノードです。Nokogiri::HTML::Element? 等で返ります。Nokogiri::HTML.parse(このinputタグ) のようなものです。
再設定することがある場合は #node= を使用します。

この入力欄の値を文字列で返します。
デフォルトは元の入力フォームの HTML の value 属性の文字列(または textarea タグに挟まれた文字列)です。
<input type="text" name="oneliner" value="1行テキスト">
という HTML で表される入力欄オブジェクトだった場合、value メソッドは 1行テキスト を返します。
<textarea name="multi">テキスト1行目
テキスト2行目</textarea>
という HTML で表される入力欄オブジェクトだった場合には、value メソッドは "テキスト1行目\nテキスト2行目" を返します。
ともに HTML 上での改行は Nokogiri によって "\n" に揃えられ、HTML の文字参照は Mechanize::Util.html_unescape で解決されています。value 相当が空の場合(value="" や <textarea></textarea>)は空文字列 "" を、value 属性自体が存在しない場合は nil を返します。
変更(というか入力)は #value= で行います。ユーザーによる入力内容の改行等は変換せずそのまま返します。

入力内容を返す #value メソッドの返り値を文字列 str に変更します。
通常の Web ブラウザでは「入力欄(の空欄)にキーボードで文字列を入力する」という行為に該当します。
入力文字列の文字エンコーディングは UTF-8(と互換性のあるもの)でなければなりません。この入力欄のあるページの Mechanize::Page#encoding に Iconv 経由で変換して送信されます。改行はそのまま送られます。



HTML 上での出現位置を引数のオブジェクトと比較し、sort 可能な答を返します。ユーザーが使用することはありません。
other と比べて自分が前なら -1 を、自分が後ろなら 1 を、同一 #node 由来なら 0 を返します。
引数の other は other.node が Nokogiri の HTML ノードオブジェクトを返すものならなんでも構いません(Nokogiri のオブジェクトの <=> メソッドの機能を利用しています)。これにより、Mechanize のフォームやその部品のオブジェクトは、配列で sort すると HTML での出現順にきっちり並びます。残念ながらリンクは <=> メソッドがないので一発ではできません(links.sort_by{|e| e.node} してください)。
なお、Mechanize が内部で作成する擬似的入力欄の場合、node が Hash であることがありますが、自分の node が Hash なら 1 を、引数のオブジェクトの node が Hash なら -1 を返します。

この入力欄の名前を返す #name メソッドの返り値を文字列 str に変更します。
あまり利用機会のあるメソッドではありませんが、name を変更した場合は実際の送信文字列の「キー」部分もその値に変更されてしまうので気をつけてください。name がないフィールドを選択したい場合は、名前を付けるのではなく Mechanize::Form#field_with で form_with(:name => nil) と指定するとうまくいきます。あるいは Mechanize::Form#fields で配列として取り出しても構いません。

この入力欄の HTML ノードを返す #node メソッドの返り値を node_obj に変更します。
node_obj は Nokogiri::HTML::Element? などです。
各種 HTML 属性値解釈は Field オブジェクト作成時に行われているため、このメソッドを使用して node を(Page#parser=のように「遅延」で)再設定してもオブジェクトの動作は変わりません。

Mechanize がサーバへ送信する文字列を作成する際に使用される、ネストした配列を返します。
Mechanize::Form#build_query から呼ばれています。ユーザーが使用することはありません。
#name#value を組にした配列を返します。#value が nil だった場合は空文字列 "" を使用します。
このメソッドの返り値の文字列自体は UTF-8 ですが、送信時に Mechanize::Util.from_native_charsetMechanize::Page#encoding のエンコーディング値に変換されます。