ライター アクセサーをチェックインしたいと考えています。私の最初のアイデアはブール値を返すことでした。
class MyClass
def var=(var)
@var = var
# some checking
return true
end
end
m = MyClass.new
retval = (m.var = 'foo')
=> "foo"
ライター アクセサーで戻り値を設定できますか? はいの場合、どうすればこの値を取得できますか?
あなたがやろうとしていることの代わりに set_var(var) を使用します。属性ライターは単に機能すると想定されています。あなたがやろうとしていることは非標準的であり、次の貧しい人があなたのコードを使用することは明らかではありません. (それはあなた自身かもしれません)悪い入力が送信された場合、またはかなり例外的なことが発生した場合、例外をスローします。
この動作が必要です
Correct
>>temp = object.var = 7
=> 7
Wrong
>>temp = object.var = 7
=> false
= 演算子は、渡された値を常に返す必要があります。Ruby は、プログラミング言語では珍しい暗黙の戻り値を使用します。を使用するときは、リターンを再確認してくださいmethod=()
。
class Test
def var=(var)
@var = var
return true
end
end
t1, t2 = Test.new, Test.new
t1.var = 123 # evaluates to 123
# Why is it impossible to return something else:
t1.var = t2.var = 456
コメントで述べたように:連鎖割り当てを許可するために戻り値を変更することは不可能だと思います。とにかく、Rubyプログラマーの大多数は、戻り値を変更することはおそらく予想外のことです。
免責事項:上記のコードをテストしましたが、ステートメントを検証するための明示的な参照は見つかりませんでした。
アップデート
class Test
def method_missing(method, *args)
if method == :var=
# check something
@var = args[0]
return true
else
super(method, *args)
end
end
def var
@var
end
end
t = Test.new
t.var = 123 # evaluates to 123
t.does_not_exists # NoMethodError
それは本当に不可能に思えます!上記のサンプルは、戻り値がメソッドにまったく関係していないvar=
ことを示しています。この動作を変更することはできません。これは、Rubyの割り当てが機能する基本的な方法です。
アップデート2:解決策が見つかりました
例外を発生させることができます!
class Test
def var=(var)
raise ArgumentError if var < 100 # or some other condition
@var = var
end
def var
@var
end
end
t = Test.new
t.var = 123 # 123
t.var = 1 # ArgumentError raised
t.var # 123
また、あなたの例によれば、物事をきれいにするために、次のことができます:
class MyClass
attr_accessor :var
end
m = MyClass.new
m.var = "Test"
puts m.var # => "Test"
あなたの質問に関してですが、オブジェクトの値に設定したもの以外の値を返すことができるかどうかを尋ねていますか?
アップデート
このプロジェクトをチェックしてください: Validatable . クラス属性に ActiveRecord のような検証を追加します。
簡単なシナリオ:
class Person
include Validatable
validates_presence_of :name
attr_accessor :name
end
class PersonPresenter
include Validatable
include_validations_for :person
attr_accessor :person
def initialize(person)
@person = person
end
end
presenter = PersonPresenter.new(Person.new)
presenter.valid? #=> false
presenter.errors.on(:name) #=> "can't be blank"
私はこれが党への遅い応答であることを知っています...
クラスで何をしようとしているのかを知るのは難しいです。データベースに保存する前に確認したいということでしたか? ファイル?
属性値が不適切な場合はどうしたいですか?
ブール値の戻り値を使用することで、エラーを効果的に「隠す」ことができます (セッターの戻り値をチェックしなければならないという奇妙なことを忘れてしまうため) 。
他の人が提案したことを行うことができますが、
isValid? を検討することもできます。最終的に永続化される多くのクラスのようなメソッド。次に、保存でオブジェクトの状態を確認し、エラーをスローできます。
結論:
ソリューションを推進するのに役立つ 1 つの方法は、探している動作を最初に記述することを検討することです (つまり、BDD )。次に、 RSpecを使用してTDDを実行し、目的の動作をサポートするために出現する必要がある目的のクラス「コントラクト」を取得することによって、クラスが何をすべきかをさらに調べます。