2012-05-17 2 views
1

일부 Rspec 내용을 배우고 실수로 모델 클래스에 일부 코드를 입력하여 오류가 발생할 것으로 예상했습니다. 그러나 놀랍게도 거기에는 없었습니다.Ruby 클래스 정의에 임의 코드를 추가 할 수있는 이유는 무엇입니까?

Arman$ rails console 
Loading development environment (Rails 3.2.3) 
1.9.3p194 :001 > a = Address.new 
Hey! I shouldn't be able to do this 
=> #<Address id: nil, street: nil, city: nil, zip: nil, country: nil, person_id: nil, created_at: nil, updated_at: nil> 
1.9.3p194 :002 > 

왜 이상한 코드가 클래스 정의 내부에 추가되는 불평 루비되지 않습니다

class Address < ActiveRecord::Base 
    attr_accessible :city, :country, :person_id, :street, :zip 
    validates_presence_of :city, :zip, :street 
    before_save :setDefaultCountry 

    # -- Beginning strange code -- 

    if true 
    puts "Hey! I shouldn't be able to do this" 
    end  

    # -- End of strange code -- 

    private 
    def setDefaultCountry 
    if self.country.blank? 
     self.country = "US" 
    end 
    end 
end 

이 레일 콘솔 출력은?

답변

2

그건 루비가 작동하는 방법입니다. attr_accessible으로 인해 오류가 발생한다고 생각하지 않습니까? 그러나 이것은 단지 일반적인 메서드 호출입니다! Here's its source

# File activerecord/lib/active_record/base.rb, line 1083 
def attr_accessible(*attributes) 
    write_inheritable_attribute(:attr_accessible, 
           Set.new(attributes.map(&:to_s)) + (accessible_attributes || [])) 
end 

클래스 정의에서 임의의 루비 코드를 실행할 수 있습니다. 이것은 기능이 아니라 버그입니다 :)

+0

사실'attr_accessible'는'해시'입니다. 그래서 나는 그것을 필드를 초기화하는 것으로 본다. – Roman

+0

"해시"란 무엇을 의미합니까? –

+0

'puts attr_accessible.class'를 시도 할 때'Hash'를 출력합니다. – Roman

3

class 블록은 코드 실행을위한 새로운 컨텍스트를 도입하기 때문에. Ruby는 C++이 아닌 Ruby입니다. 클래스 정의 중에 일부 코드를 실행하려면 왜 우리가 할 수 없어야한다고 생각합니까? 코드를 내부에서 올바르게 실행할 수 있습니다.이 동안 self은 해당 클래스의 인스턴스 대신 클래스를 나타내는 Class 개체를 가리 킵니다. 이것은 당신에게 큰 유연성을 주며 Ruby 원숭이 - 패치 가능 (루비스트의 관점에서 보았을 때, 많은 사람들이 연습에서 눈살을 찌푸린 다하더라도) 할 수있는 큰 요소 중 하나입니다.

관련 문제