2013-01-16 4 views
1

그래서 저는 rspec/mocha의 mock과 비슷한 것을하고 싶습니다. 그러나 두 가지 객체에 대해서만, 그리고 그 모두는 아닙니다. 이것은 내가 지금까지 무엇을 가지고 :알 수없는 유형의 객체에서 객체의 인스턴스에 define_method를 사용하는 방법은 무엇입니까?

mock(self.instantiated, :sections, sections) 

과 : 내가 좋아하는 일을 할 수 그럼 https://stackoverflow.com/a/185969/356849

을 :이 게시물에서 그런 식으로 쓸 생각이있어

def mock(obj, method_to_mock, value) 
    obj.class << obj do 
     define_method(method_to_mock) do 
      return value 
     end 
    end 
end 

내가 self.instantiatedsections에 저장 한 객체를 내 객체 배열 sections으로 덮어 씁니다.

제가 이것을하고있는 이유는 객체의 직렬화되고 암호화 된 버전을 저장하고 있기 때문에 객체를 암호화 해제하고 직렬화 해제 할 수 있기를 원합니다. 마치 데이터베이스에서 읽은 것처럼 내 뷰에서 해당 개체를 볼 수 있습니다. 그러나 그것은 중요하지 않으며, 대부분은 끝났습니다.

그래서, 나는이 작업을 수행 할 수 있도록하려면 :

mock(<Instance of object>, :<method of object that is going to be overridden, to avoid db access>, <the stuff to return when the overridden method is invoked)

을 현재,이 함께 obj.class << obj do 줄에 오류를 받고 있어요 :

NoMethodError: undefined method `obj' for #<MyObject::Encrypted:0x7f190eebcd18> 

아이디어를?


UPDATE

class << obj는 지금 무한 루프에 두번째 라인을 바꿨다.

from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/connection_adapters/abstract/connection_pool.rb:351:in `retrieve_connection_pool' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/connection_adapters/abstract/connection_pool.rb:351:in `retrieve_connection_pool' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/connection_adapters/abstract/connection_pool.rb:325:in `retrieve_connection' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/connection_adapters/abstract/connection_specification.rb:123:in `retrieve_connection' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/connection_adapters/abstract/connection_specification.rb:115:in `connection' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/base.rb:1305:in `columns' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/base.rb:1318:in `column_names' 
from /home/me/.rvm/gems/[email protected]/gems/searchlogic-2.4.28/lib/searchlogic/named_scopes/ordering.rb:35:in `ordering_condition_details' 
from /home/me/.rvm/gems/[email protected]/gems/searchlogic-2.4.28/lib/searchlogic/named_scopes/ordering.rb:26:in `method_missing' 
from /home/me/.rvm/gems/[email protected]/gems/searchlogic-2.4.28/lib/searchlogic/named_scopes/or_conditions.rb:28:in `method_missing' 
from /home/me/.rvm/gems/[email protected]/gems/activerecord-2.3.15/lib/active_record/base.rb:2002:in `method_missing_without_paginate' 
from /home/me/.rvm/gems/[email protected]/gems/will_paginate-2.3.16/lib/will_paginate/finder.rb:170:in `method_missing_without_attr_encrypted' 
from /home/me/.rvm/gems/[email protected]/bundler/gems/attr_encrypted-a4b25f01d137/lib/attr_encrypted/adapters/active_record.rb:50:in `method_missing' 
from /home/me/Work/GravityLabs/project/app/models/proposal/encrypted.rb:119:in `mock' 
from /home/me/Work/GravityLabs/project/app/models/proposal/encrypted.rb:79:in `instantiate' 
from /home/me/Work/GravityLabs/project/app/models/proposal/encrypted.rb:58:in `each' 
from /home/me/Work/GravityLabs/project/app/models/proposal/encrypted.rb:58:in `instantiate' 
+1

'클래스 << self' 입력하는 특별한 표현이다 자기의 싱글 톤 클래스. 'class << obj'를 시도하십시오. 'class'는 키워드가 아니라 메소드입니다. – BernardK

+0

이제 무한 루프가되었습니다. 영형.내 생각 엔 이제는 obj가 아닌 모든 인스턴스에 대해 새로운 메소드를 정의했다는 것입니다. : - \ – NullVoxPopuli

답변

1

obj.class << obj do는 의미가 없습니다. 당신은 아마 말하고 싶었다 무엇

def mock(obj, method_to_mock, value) 
    (class << obj; self; end).class_eval do 
    define_method(method_to_mock) do 
     return value 
    end 
    end 
end 

(class << obj; self; end).class_eval 구문은 다음, 그 싱글 톤 클래스 반환 obj의 싱글 톤 클래스를 열고 블록을 통과하는 싱글 톤 클래스에 class_eval 호출이다. 당신의 구문에서

obj.class는 다음과 같이 obj do...end을 평가 한 결과를 통과하는 << 메소드를 호출하려고하는 OBJ의 클래스 (하지의 싱글 톤 클래스)에 대한 참조를 반환하는 수신기로 obj:class 메시지를 전송 arg. objself (MyObject :: Encrypted : 0x7f190eebcd1) 메서드가 아니므로 NoMethodError를 얻습니다. 현대 루비에서

, 대신에 상대적으로 비밀을 말하는, (class << obj; self; end)는 싱글 톤 클래스를 얻기 위해, 당신은 너무처럼 singleton_class 방법을 사용할 수 있습니다 : obj.singleton_class.class_eval do ... end

+0

설명해 주셔서 감사합니다! 모든 객체가 싱글 톤 클래스를 가지고 있습니까? 내 자바 시대의 싱글 톤은 단지 한 번만 인스턴스화 할 수있는 클래스라는 것을 기억합니다. – NullVoxPopuli

+1

루비에서 모든 객체는 싱글 톤 클래스를가집니다. 때로는 메타 클래스 또는 고유 클래스라고도합니다. 루비 싱글 톤 클래스는 기본적으로 객체와 기본 클래스 사이의 조상 체인에 삽입 된 익명 클래스입니다. 우리가 "클래스 메소드"라고 부르는 것은 사실 클래스의 싱글 톤 메소드입니다 (클래스는 루비의 객체입니다). [여기에 더 자세한 설명이 있습니다.] (http://www.devalot.com/articles/2008/09/ruby-singleton) [싱글 톤] (http://en.wikipedia.org/wiki/)과 같은 것은 아닙니다. Singleton_pattern) 인스턴스 하나만 가질 수있는 객체입니다. – dbenhur

2
def mock(obj, method_to_mock, value=nil) 
    obj.define_singleton_method(method_to_mock) do value end 
end 
+1

oops! 루비 1.8.7/레일즈 2.3.15를 사용하고 있다고 언급 했어야합니다. – NullVoxPopuli

관련 문제