2013-02-13 3 views
0

Ruby 프로그래밍에 익숙하지 않지만, 심볼 (불변 값, 적은 공간, 열거 형 등)의 포인트를 더 많이 또는 덜 얻었습니다. 다음은 저를 귀찮게합니다. 레이크 (Rake) 있는 Hartl 루비 온 레일즈 튜토리얼 시험 :Ruby Rake에서 변수와 심볼 사이의 연결은 무엇입니까?

describe "something" do 
    let(:user) { FactoryGirl.create(:user) } 
    before { sign_in user } 
... 
end 

FactoryGirl.create(:user) 전화를 나에게 의미가 있습니다 - 여기 우리가 FactoryGirl에 플래그 (:user)의 종류를 전달하는 객체의 종류를 만들기 위해 그에게 (또는 더 정확하게는 User 객체 만 생성하기 때문에 어떤 변수를 설정해야하는지). 그러나 let(user)에서 user은 변수가 아니며 기호가 아닙니다 (또는 적어도 있어야합니다). 나는 let 메서드가 같은 이름의 변수에 대해 :user 심볼을 비밀리에 스와핑한다고 추측 할 수 있습니다.하지만 그 이유는 무엇입니까? let(user)은 훨씬 더 직관적 인 구문이 아니겠습니까? 내가 여기서 무엇을 놓치고 있니?

또한이 패턴이 루비에서 발생하는 다른 장소가 있습니까? 지금까지 나는 레이크 테스트에서만 이것을 보았습니다.

+1

나는 도움이되지는 않지만 소스 코드 (https://github.com/rspec/rspec-core/blob/v2.12.2/lib/rspec/core/let)를 살펴 본다.rb # L31)는'let'이 주어진 이름을 가진 메소드를 정의 할 것이라는 것을 보여줍니다. 그래서 제 생각에는 변수에 심볼을주는 것이 합리적입니다. 따라서 메소드는 변수가 아니라 적절하게 명명됩니다. – pjam

답변

0

몇 가지 사소한 수정/해명 :

  1. 이것은 'RSpec에'테스트가 아닌 레이크 테스트입니다. Rake는 자동화 도구 ('make'와 유사)이지만 rspec은 테스트 도구입니다.
  2. FactoryGirl은 다양한 종류의 개체를 만들 수 있습니다. 여러 팩토리를 정의하면 #create로 전달 된 심볼이 사용할 팩토리를 알려줍니다. 그것은 당신의 프로그램에서 어떤 변수를 설정 할지를 말하지 않습니다.
  3. let() 호출은 제공된 심볼의 이름으로 주어진 헬퍼 메소드를 정의합니다. :사용자. 메서드는 전달 된 블록에 의해 결정된 값을 반환합니다. FactoryGirl이 생성 할 사용자 객체입니다.

let() 물건에 대한 자세한 내용을 살펴 보았습니다. 실제 문서 위치 :이 특정 패턴이 NC 내 개인적인 경험에서

https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and-let

하지만, 단위 테스트가 그들과 함께 아이디어 코드를 행사하기 때문에 일반 코드와 다른 경향이 해결하지 실제 문제. 그렇게하기 위해서는 한 번에 하나씩 바꿔야하는 경향이 있습니다. 따라서 루비는 타이핑을 줄이고 여전히 읽을 수있는 많은 도구를 제공합니다.

편집 :이 패턴을 사용하는 예제에 대한 설명을 참조하십시오. 내 코 바로 아래에 ... :)

+0

메소드에 이름을 전달합니다. 그 이름을 사용하는 또 다른 메소드를 생성하는 것은 확실히 RSpec에 고유 한 패턴이 아닙니다. 예를 들어, 코어 라이브러리에는'Module # attr_reader', 모듈 # attr_writer' 및 모듈 # attr_accessor가 있습니다. 그리고'Module # alias_method'. –

+0

좋은 지적! 그것들은 훌륭한 예입니다. –

2

Dave가 이미 언급했듯이 제공된 코드는 레이크 작업이 아니라 RSpec 사양입니다.

하지만 여기서 진짜 문제에 집중하겠습니다.

기호가 비슷한 기능을 가진 다른 언어와 접촉 할 수 없다면 처음에는 쉽게 구하기가 쉽지 않습니다. 어떤 언어는 그것을 Atom이라고 부릅니다.

http://en.wikipedia.org/wiki/Symbol_(programming)

기호를 behing 생각은 인간적으로 읽을 수 있지만 계산 저렴 기본 유형을 제공하는 것입니다.

루비에서는 컴파일러/인터프리터가 심볼을 볼 때 심볼 유형의 객체를 만들어 메모리에 저장합니다.루비에서 심볼은 싱글 톤이므로 동일한 심볼을 다른 용도로 사용하면 똑같은 객체를 반환하므로 공간 대신 ​​정말로 저렴하고 비교할 수 없을만큼 저렴합니다. 컨텐츠 대신 메모리 주소를 비교할 수 있기 때문입니다. 이 같은 두 개의 문자, 비교 예를 들어

는 : 전용 메모리 주소를 의미

:foo == :foo 

당신은 거의 동일한 개체를 비교하고는 비교 될 필요가있다. 이제

, 당신은 두 문자열을 비교할 때 :

"foo" == "foo" 

그것은 동일한 내용으로 문자열의 두 인스턴스를 생성하고, 그들이 동일한 확인하기 위해 문자열의 각 바이트를 비교할 필요가있다.

이 속성은 기호를 해시의 식별자 나 키에 유용하게 만듭니다.

이제 RSpec.

는 이제 다음 예를 보자 :

describe Authenticator do 
    let(:user) { Factory.create(:user)) 

    it "authenticate" do 
    auth_user = subject.authenticate(user.login, user.password) 
    auth_user.should == user 
    end 
end 

Factory.create 사용하는 공장의 식별자로 기호를합니다. 여러분은 공장을 직접 정의 할 필요가 있습니다. 문자열을 사용할 수는 있지만 상징을 사용하는 것이 더 저렴하고 모범 사례이지만 솔직히 말해서 Factory.create를 수천 번 호출하지 않으면 별 차이가 없습니다. ,

  1. 방법은 사양 (IT 블록) 내에서 호출되어 처음으로,이 블록을 실행합니다 :

    는하자가 실제로 몇 가지 작업을 수행하는 방법을 정의하는 것, 변수를 정의하지 않습니다 결과를 캐쉬하고 그것을 반환한다.

  2. 같은 사양 (블록) 내의 다른 모든 호출은 캐시 된 결과를 반환 할 것이다.
  3. 사양이 완료된 후에 캐시 된 결과를 삭제하기 때문에 다음에 다시 재평가된다. 전화, 다음 사양에

이렇게하면 필요한 경우에만 느슨하게 객체를 만들 수 있으며 상태 변경을 현재 사양으로 제한 할 수 있습니다.

RSpec은 기호를 특정 물건을 추상화하기 위해 생성되는 메소드 이름의 식별자로 기호를 사용하여보다 쉽게 ​​사용합니다. RSpec은 테스트 스위트를 만들기 위해 메타 프로그래밍을 사용하는 BDD 도메인 특정 언어 일뿐입니다. 당신은 아마 이런 테스트 케이스를 쓰지한다

class AuthenticatorTest < Test::Unit::TestCase 
    def user 
    return @user if @user 
    @user = Factory.create(:user) 
    end 

    def subject 
    return @subject if @subject 
    @subject = Authenticator.new 
    end 

    def teardown 
    @subject = nil 
    @user = nil 
    end 

    def test_authenticate 
    auth_user = subject.authenticate(user.login, user.password) 
    assert_equal auth_user, user 
    end 
end 

참고하지만, (약)는 RSpec에는 무엇을 보여

같은 문제

는 다음 테스트 케이스 달성 할 수있다.

도움이 되었기를 바랍니다.

관련 문제