액티브 서포트 코어 익스텐션
액티브 서포트는 루비 언어 익스텐션과 유틸리티를 제공하는 Ruby on Rails 구성 요소입니다.
이는 Rails 애플리케이션 개발과 Ruby on Rails 자체 개발을 위해 언어 수준에서 더 풍부한 기능을 제공합니다.
이 가이드를 읽고 나면 다음을 알 수 있습니다:
- 코어 익스텐션이 무엇인지.
- 모든 익스텐션을 로드하는 방법.
- 원하는 익스텐션만 선택적으로 로드하는 방법.
- 액티브 서포트가 제공하는 익스텐션.
코어 익스텐션 로드하기
독립형 액티브 서포트
기본 footprint를 최소화하기 위해 액티브 서포트는 기본적으로 최소한의 종속성만 로드합니다. 원하는 익스텐션만 로드할 수 있도록 작은 조각으로 나뉘어 있습니다. 또한 관련 익스텐션을 한 번에 모두 로드할 수 있는 편의 진입점도 있습니다.
따라서 다음과 같은 간단한 require 문으로:
require "active_support"
액티브 서포트 프레임워크에 필요한 익스텐션만 로드됩니다.
정의 선택적으로 로드하기
이 예제는 Hash#with_indifferent_access
를 로드하는 방법을 보여줍니다. 이 익스텐션은 키를 문자열이나 기호로 접근할 수 있는 ActiveSupport::HashWithIndifferentAccess
로 해시를 변환합니다.
{ a: 1 }.with_indifferent_access["a"] # => 1
이 가이드에서 각 코어 익스텐션 메서드에 대해 정의된 위치를 알려주는 주석이 있습니다. with_indifferent_access
의 경우 다음과 같은 주석이 있습니다:
주석: active_support/core_ext/hash/indifferent_access.rb
에 정의되어 있습니다.
이는 다음과 같이 로드할 수 있다는 뜻입니다:
require "active_support" require "active_support/core_ext/hash/indifferent_access"
액티브 서포트는 엄격하게 필요한 종속성만 로드하도록 주의 깊게 수정되었습니다.
그룹화된 코어 익스텐션 로드하기
다음 단계는 Hash
에 대한 모든 익스텐션을 한 번에 로드하는 것입니다. 일반적으로 SomeClass
에 대한 익스텐션은 active_support/core_ext/some_class
를 로드하면 한 번에 사용할 수 있습니다.
따라서 Hash
에 대한 모든 익스텐션(including with_indifferent_access
)을 로드하려면:
require "active_support" require "active_support/core_ext/hash"
모든 코어 익스텐션 로드하기
모든 코어 익스텐션을 로드하고 싶다면 다음 파일을 로드하면 됩니다:
require "active_support" require "active_support/core_ext"
모든 액티브 서포트 로드하기
마지막으로 모든 액티브 서포트를 사용하고 싶다면 다음과 같이 하면 됩니다:
require "active_support/all"
이렇게 하면 메모리에 전체 액티브 서포트가 올라가지 않습니다. 일부 기능은 autoload
를 통해 구현되어 있어 사용될 때만 로드됩니다.
Ruby on Rails 애플리케이션 내에서 액티브 서포트
Ruby on Rails 애플리케이션은 config.active_support.bare
가 true가 아닌 한 모든 액티브 서포트를 로드합니다. 이 경우 프레임워크 자체가 선택한 것만 로드되며, 이전 섹션에서 설명한 것처럼 원하는 수준의 세부사항까지 선택적으로 로드할 수 있습니다.
모든 객체에 대한 익스텐션
blank?
및 present?
다음과 같은 값들은 Rails 애플리케이션에서 비어 있는 것으로 간주됩니다:
nil
과false
,공백 문자로만 구성된 문자열(아래 주석 참고),
빈 배열과 해시, 그리고
empty?
에 응답하고 비어 있는 기타 객체.
정보: 문자열에 대한 술어는 유니코드 인식 문자 클래스 [:space:]
를 사용하므로, 예를 들어 U+2029(문단 구분자)도 공백으로 간주됩니다.
경고: 숫자는 언급되지 않았다는 점에 유의하세요. 특히 0과 0.0은 비어 있지 않습니다.
예를 들어, ActionController::HttpAuthentication::Token::ControllerMethods
의 이 메서드는 토큰이 있는지 확인하기 위해 blank?
를 사용합니다:
def authenticate(controller, &login_procedure) token, options = token_and_options(controller.request) unless token.blank? login_procedure.call(token, options) end end
present?
메서드는 !blank?
와 동등합니다. 이 예제는 ActionDispatch::Http::Cache::Response
에서 가져온 것입니다:
def set_conditional_cache_control! unless self["Cache-Control"].present? # ... end end
주석: active_support/core_ext/object/blank.rb
에 정의되어 있습니다.
presence
presence
메서드는 present?
이면 자신을 반환하고, 그렇지 않으면 nil
을 반환합니다. 다음과 같은 관용구에 유용합니다:
host = config[:host].presence || "localhost"
주석: active_support/core_ext/object/blank.rb
에 정의되어 있습니다.
duplicable?
Ruby 2.5부터 대부분의 객체는 dup
또는 clone
을 통해 복제할 수 있습니다:
"foo".dup # => "foo" "".dup # => "" Rational(1).dup # => (1/1) Complex(0).dup # => (0+0i) 1.method(:+).dup # => TypeError (allocator undefined for Method)
액티브 서포트는 duplicable?
를 제공하여 객체의 복제 가능 여부를 확인할 수 있습니다:
"foo".duplicable? # => true "".duplicable? # => true Rational(1).duplicable? # => true Complex(1).duplicable? # => true 1.method(:+).duplicable? # => false
경고: 어떤 클래스든 dup
와 clone
을 제거하거나 예외를 발생시켜 복제를 금지할 수 있습니다. 따라서 임의의 객체가 복제 가능한지 확인하려면 rescue
만이 답변을 줄 수 있습니다. duplicable?
는 위의 하드 코딩된 목록에 의존하지만, rescue
보다 훨씬 빠릅니다. 이 하드 코딩된 목록이 사용 사례에 충분한 경우에만 사용하세요.
주석: active_support/core_ext/object/duplicable.rb
에 정의되어 있습니다.
deep_dup
deep_dup
메서드는 주어진 객체의 깊은 복사본을 반환합니다. 일반적으로 객체에 다른 객체가 포함되어 있을 때 dup
를 하면 Ruby는 그것들을 복사하지 않고 얕은 복사를 만듭니다. 예를 들어 문자열이 포함된 배열이 있다면 다음과 같습니다:
array = ["string"] duplicate = array.dup duplicate.push "another-string" # 객체가 복제되었으므로 요소는 복제된 배열에만 추가되었습니다. array # => ["string"] duplicate # => ["string", "another-string"] duplicate.first.gsub!("string", "foo") # 첫 번째 요소가 복제되지 않았으므로 두 배열 모두 변경되었습니다. array # => ["foo"] duplicate # => ["foo", "another-string"]
객체의 깊은 복사본이 필요한 경우 deep_dup
를 사용해야 합니다. 다음은 예시입니다:
array = ["string"] duplicate = array.deep_dup duplicate.first.gsub!("string", "foo") array # => ["string"] duplicate # => ["foo"]
객체가 복제 불가능한 경우 deep_dup
는 그냥 객체 자체를 반환합니다:
number = 1 duplicate = number.deep_dup number.object_id == duplicate.object_id # => true
주석: active_support/core_ext/object/deep_dup.rb
에 정의되어 있습니다.
try
객체가 nil
이 아닌 경우에만 메서드를 호출하고 싶을 때 가장 간단한 방법은 조건문을 사용하는 것이지만, 불필요한 복잡성을 야기합니다. 대신 try
를 사용할 수 있습니다. try
는 Object#public_send
와 유사하지만, 대상이 nil
이면 nil
을 반환합니다.
다음은 예시입니다:
try 없이
unless @number.nil? @number.next end
try 사용
@number.try(:next) “`
다른 예로, @logger
가 nil
일 수 있는 ActiveRecord::ConnectionAdapters::AbstractAdapter
의 코드를 보면 try
를 사용하여 불필요한 검사를 피하고 있습니다.
def log_info(sql, name, ms) if @logger.try(:debug?) name = "%s (%.1fms)" % [name || "SQL", ms] @logger.debug(format_log_entry(name, sql.squeeze(" "))) end end
try
는 인수 없이 블록으로 호출할 수도 있습니다. 이 경우 객체가 nil
이 아닌 경우에만 블록이 실행됩니다:
@person.try { |p| "#{p.first_name} #{p.last_name}" }
try
는 메서드 없음 오류를 삼켜 nil
을 반환합니다. 타이핑 오류를 방지하려면 try!
를 대신 사용하세요:
@number.try(:nest) # => nil @number.try!(:nest) # NoMethodError: undefined method `nest' for 1:Integer
주석: active_support/core_ext/object/try.rb
에 정의되어 있습니다.
class_eval(*args, &block)
[class_eval
][Kernel#class_eval]을 사용하면 임의의 객체의 싱글톤 클래스에서 코드를 평가할 수 있습니다:
class Proc def bind(object) block, time = self, Time.current object.class_eval do method_name = "__bind_#{time.to_i}_#{time.usec}" define_method(method_name, &block) metho네, 번역을 계속하겠습니다. ### `acts_like?(duck)` [`acts_like?`][Object#acts_like?] 메서드는 간단한 규약에 따라 어떤 클래스가 다른 클래스처럼 동작하는지 확인할 수 있습니다: `String`과 같은 인터페이스를 제공하는 클래스는 ```ruby def acts_like_string? end
와 같이 정의합니다. 이는 단순한 표식일 뿐, 메서드 본문이나 반환 값은 중요하지 않습니다. 그리고 클라이언트 코드는 다음과 같이 오리 타입 안전성을 쿼리할 수 있습니다:
some_klass.acts_like?(:string)
Rails에는 Date
나 Time
처럼 행동하는 클래스가 있으며, 이 계약을 따릅니다.
주석: active_support/core_ext/object/acts_like.rb
에 정의되어 있습니다.
to_param
모든 객체는 Rails에서 to_param
메서드를 구현하며, 이는 쿼리 문자열이나 URL 조각에서 해당 객체를 나타내는 값을 반환하는 것이 목적입니다.
기본적으로 to_param
은 to_s
를 호출합니다:
7.to_param # => "7"
to_param
의 반환 값은 이스케이프되지 않아야 합니다:
"Tom & Jerry".to_param # => "Tom & Jerry"
Rails의 여러 클래스에서 이 메서드를 재정의합니다.
예를 들어 nil
, true
, false
는 자신을 반환합니다. Array#to_param
은 요소의 to_param
을 호출하고 결과를 ”/“로 연결합니다:
[0, true, String].to_param # => "0/true/String"
특히 Rails 라우팅 시스템은 모델의 to_param
을 호출하여 :id
자리 표시자의 값을 얻습니다. ActiveRecord::Base#to_param
은 모델의 id
를 반환하지만, 모델에서 이 메서드를 재정의할 수 있습니다. 예를 들어 다음과 같이 정의하면:
class User def to_param "#{id}-#{name.parameterize}" end end
다음과 같이 사용할 수 있습니다:
user_path(@user) # => "/users/357-john-smith"
경고. 컨트롤러는 to_param
의 재정의를 인식해야 합니다. 왜냐하면 그런 요청이 들어오면 "357-john-smith"가 params[:id]
의 값이 되기 때문입니다.
주석: active_support/core_ext/object/to_param.rb
에 정의되어 있습니다.
to_query
to_query
메서드는 주어진 key
와 to_param
의 반환 값을 연결하여 쿼리 문자열을 생성합니다. 예를 들어 다음과 같은 to_param
정의가 있다면:
class User def to_param "#{id}-#{name.parameterize}" end end
다음과 같이 사용할 수 있습니다:
current_user.to_query("user") # => "user=357-john-smith"
이 메서드는 키와 값 모두 필요한 부분을 이스케이프합니다:
account.to_query("company[name]") # => "company%5Bname%5D=Johnson+%26+Johnson"
따라서 쿼리 문자열에 바로 사용할 수 있습니다.
배열은 각 요소에 대해 to_query
를 호출하고 key[]
를 키로 사용한 뒤 결과를 ”&“로 연결합니다:
[3.4, -45.6].to_query("sample") # => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
해시도 to_query
에 응답하지만 시그니처가 다릅니다. 인수를 전달하지 않으면 키/값 할당을 호출하고 결과를 ”&“로 연결합니다:
{ c: 3, b: 2, a: 1 }.to_query # => "a=1&b=2&c=3"
Hash#to_query
메서드는 선택적으로 네임스페이스를 받습니다:
{ id: 89, name: "John Smith" }.to_query("user") # => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
주석: active_support/core_ext/object/to_query.rb
에 정의되어 있습니다.
with_options
with_options
메서드는 일련의 메서드 호출에서 공통 옵션을 추출할 수 있는 방법을 제공합니다.
기본 옵션 해시가 주어지면, with_options
는 블록에 프록시 객체를 전달합니다. 블록 내에서 프록시에 대한 메서드 호출은 옵션이 병합된 상태로 수신기에 전달됩니다. 예를 들어, 다음과 같은 중복을 제거할 수 있습니다:
class Account < ApplicationRecord has_many :customers, dependent: :destroy has_many :products, dependent: :destroy has_many :invoices, dependent: :destroy has_many :expenses, dependent: :destroy end
다음과 같이 작성할 수 있습니다:
class Account < ApplicationRecord with_options dependent: :destroy do |assoc| assoc.has_many :customers assoc.has_many :products assoc.has_many :invoices assoc.has_many :expenses end end
이 관용구는 그룹화를 독자에게 전달할 수도 있습니다. 예를 들어 사용자별 언어로 뉴스레터를 보내고 싶다고 가정해 보겠습니다. 메일러 내부에서 다음과 같이 그룹화할 수 있습니다:
I18n.with_options locale: user.locale, scope: "newsletter" do |i18n| subject i18n.t :subject body i18n.t :body, user_name: user.name end
팁: with_options
는 수신기에 호출을 전달하므로 중첩할 수 있습니다. 각 중첩 수준은 자신의 기본값 외에 상속된 기본값도 병합합니다.
주석: active_support/core_ext/object/with_options.rb
에 정의되어 있습니다.
JSON 지원
액티브 서포트는 json
젬이 일반적으로 제공하는 것보다 Ruby 객체에 대한 to_json
의 구현이 더 나은 버전을 제공합니다. 이는 Hash
와 Process::Status
와 같은 일부 클래스가 적절한 JSON 표현을 제공하기 위해 특별한 처리가 필요하기 때문입니다.
주석: active_support/core_ext/object/json.rb
에 정의되어 있습니다.
인스턴스 변수
액티브 서포트는 인스턴스 변수에 대한 액세스를 쉽게 하는 여러 메서드를 제공합니다.
instance_values
instance_values
메서드는 인스턴스 변수 이름(@ 제외)을 키로, 해당 값을 값으로 하는 해시를 반환합니다:
class C def initialize(x, y) @x, @y = x, y end end C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
주석: active_support/core_ext/object/instance_variables.rb
에 정의되어 있습니다.
instance_variable_names
instance_variable_names
메서드는 각 이름에 ”@“가 포함된 배열을 반환합니다.
class C def initialize(x, y) @x, @y = x, y end end C.new(0, 1).instance_variable_names # => ["@x", "@y"]
주석: active_support/core_ext/object/instance_variables.rb
에 정의되어 있습니다.
경고 및 예외 억제
silence_warnings
및 enable_warnings
메서드는 블록의 지속 기간 동안 $VERBOSE
의 값을 변경한 후 다시 원래대로 설정합니다:
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
suppress
메서드를 사용하면 예외도 억제할 수 있습니다. 이 메서드는 임의의 수의 예외 클래스를 받습니다. 블록 실행 중 예외가 발생하고 인수 중 하나와 kind_of?
되면 suppress
가 예외를 캡처하고 조용히 반환합니다. 그렇지 않으면 예외가 캡처되지 않습니다:
# 사용자가 잠겨 있으면 증가가 손실되지만 큰 문제는 아닙니다. suppress(ActiveRecord::StaleObjectError) do current_user.increment! :visits end
주석: active_support/core_ext/kernel/reporting.rb
에 정의되어 있습니다.
in?
in?
술어는 객체가 다른 객체에 포함되어 있는지 테스트합니다. 인수가 include?
에 응답하지 않으면 ArgumentError
예외가 발생합니다.
in?
의 예:
1.in?([1, 2]) # => true "lo".in?("hello") # => true 25.in?(30..50) # => false 1.in?(1) # => ArgumentError
주석: active_support/core_ext/object/inclusion.rb
에 정의되어 있습니다.
모듈 익스텐션
속성
alias_attribute
모델 속성에는 리더, 라이터, 술어가 있습니다. alias_attribute
를 사용하면 이 세 가지 메서드가 모두 정의된 별칭을 만들 수 있습니다. 다른 별칭 메서드와 마찬가지로, 새 이름이 첫 번째 인수이고 이전 이름이 두 번째 인수입니다(할당과 같은 순서로 기억하면 좋습니다):
class User < ApplicationRecord # 이메일 열을 "login"으로 참조할 수 있습니다. # 인증 코드에 의미 있을 수 있습니다. alias_attribute :login, :email end
주석: active_support/core_ext/module/aliasing.rb
에 정의되어 있습니다.
내부 속성
하위 클래스에서 속성을 정의할 때 이름 충돌의 위험이 있습니다. 이는 라이브러리에 매우 중요합니다.
액티브네, 번역을 계속하겠습니다.
액티브 서포트는 attr_internal_reader
, attr_internal_writer
, attr_internal_accessor
매크로를 정의합니다. 이들은 해당 Ruby 내장 attr_*
대응물과 동일하게 작동하지만, 충돌 가능성이 낮은 방식으로 기본 인스턴스 변수 이름을 지정합니다.
attr_internal
매크로는 attr_internal_accessor
의 별칭입니다:
# 라이브러리 class ThirdPartyLibrary::Crawler attr_internal :log_level end # 클라이언트 코드 class MyCrawler < ThirdPartyLibrary::Crawler attr_accessor :log_level end
이전 예에서 :log_level
은 라이브러리의 공개 인터페이스에 속하지 않고 개발 용도로만 사용될 수 있습니다. 클라이언트 코드는 이 잠재적 충돌을 인식하지 못하고 자신의 :log_level
을 정의합니다. attr_internal
을 사용하면 충돌이 방지됩니다.
기본적으로 내부 인스턴스 변수의 이름은 선행 밑줄 @_log_level
과 같이 지정됩니다. 그러나 Module.attr_internal_naming_format
을 통해 구성할 수 있으며, 선행 @
와 %s
가 포함된 sprintf
와 유사한 형식 문자열을 전달할 수 있습니다.
Rails는 몇 군데에서 내부 속성을 사용합니다. 예를 들어 뷰에서:
module ActionView class Base attr_internal :captures attr_internal :request, :layout attr_internal :controller, :template end end
주석: active_support/core_ext/module/attr_internal.rb
에 정의되어 있습니다.
모듈 속성
mattr_reader
, mattr_writer
, mattr_accessor
매크로는 클래스에 대해 정의된 cattr_*
매크로와 동일합니다. 사실 cattr_*
매크로는 mattr_*
매크로의 별칭에 불과합니다. 클래스 속성을 참조하세요.
예를 들어 액티브 스토리지의 로거 API는 mattr_accessor
로 생성됩니다:
module ActiveStorage mattr_accessor :logger end
주석: active_support/core_ext/module/attribute_accessors.rb
에 정의되어 있습니다.
부모
module_parent
중첩된 명명된 모듈의 경우 module_parent
메서드는 해당 상수가 포함된 모듈을 반환합니다:
module X module Y module Z end end end M = X::Y::Z X::Y::Z.module_parent # => X::Y M.module_parent # => X::Y
모듈이 익명이거나 최상위 수준인 경우 module_parent
는 Object
를 반환합니다.
경고: 이 경우 module_parent_name
은 nil
을 반환합니다.
주석: active_support/core_ext/module/introspection.rb
에 정의되어 있습니다.
module_parent_name
중첩된 명명된 모듈의 경우 module_parent_name
메서드는 해당 상수가 포함된 모듈의 정규화된 이름을 반환합니다:
module X module Y module Z end end end M = X::Y::Z X::Y::Z.module_parent_name # => "X::Y" M.module_parent_name # => "X::Y"
최상위 수준 또는 익명 모듈의 경우 module_parent_name
은 nil
을 반환합니다.
경고: 이 경우 module_parent
는 Object
를 반환합니다.
주석: active_support/core_ext/module/introspection.rb
에 정의되어 있습니다.
module_parents
module_parents
메서드는 module_parent
를 수신기에 대해 호출하고 Object
에 도달할 때까지 계속합니다. 체인은 아래에서 위로 배열로 반환됩니다:
module X module Y module Z end end end M = X::Y::Z X::Y::Z.module_parents # => [X::Y, X, Object] M.module_parents # => [X::Y, X, Object]
주석: active_support/core_ext/module/introspection.rb
에 정의되어 있습니다.
익명
모듈은 이름이 있을 수도, 없을 수도 있습니다:
module M end M.name # => "M" N = Module.new N.name # => "N" Module.new.name # => nil
anonymous?
술어를 사용하여 모듈이 이름이 있는지 확인할 수 있습니다:
module M end M.anonymous? # => false Module.new.anonymous? # => true
접근할 수 없다고 해서 익명이 아닌 것은 아닙니다:
module M end m = Object.send(:remove_const, :M) m.anonymous? # => false
그러나 익명 모듈은 정의상 접근할 수 없습니다.
주석: active_support/core_ext/module/anonymous.rb
에 정의되어 있습니다.
메서드 위임
delegate
delegate
매크로는 메서드를 전달하는 쉬운 방법을 제공합니다.
사용자의 로그인 정보가 User
모델에 있지만 이름과 다른 데이터는 별도의 Profile
모델에 있다고 가정해 보겠습니다:
class User < ApplicationRecord has_one :profile end
이 구성에서 사용자의 이름을 얻으려면 user.profile.name
을 사용해야 합니다. 그러나 이러한 속성에 직접 액세스할 수 있다면 편리할 것입니다:
class User < ApplicationRecord has_one :profile def name profile.name end end
이것이 delegate
가 해주는 일입니다:
class User < ApplicationRecord has_one :profile delegate :name, to: :profile end
더 짧고 의도가 더 명확합니다.
메서드는 대상에서 public이어야 합니다.
delegate
매크로는 여러 메서드를 허용합니다:
delegate :name, :age, :address, :twitter, to: :profile
문자열로 보간될 때 :to
옵션은 대상 객체를 평가하는 표현식이 되어야 합니다. 일반적으로 문자열이나 기호입니다. 이 표현식은 수신기의 컨텍스트에서 평가됩니다:
# Rails 상수에 위임 delegate :logger, to: :Rails # 수신기의 클래스에 위임 delegate :table_name, to: :class
경고: :prefix
옵션이 true
이면 이것은 더 일반적이지 않습니다. 아래를 참조하세요.
기본적으로 위임으로 인해 NoMethodError
가 발생하고 대상이 nil
인 경우 예외가 전파됩니다. :allow_nil
옵션을 사용하면 대신 nil
을 반환하도록 할 수 있습니다:
delegate :name, to: :profile, allow_nil: true
allow_nil
을 사용하면 사용자에게 프로필이 없는 경우 user.name
이 nil
을 반환합니다.
:prefix
옵션은 생성된 메서드의 이름에 접두사를 추가합니다. 이는 더 나은 이름을 얻기 위해 유용할 수 있습니다:
delegate :street, to: :address, prefix: true
이전 예에서는 address_street
가 생성되었습니다.
경고: 이 경우 생성된 메서드의 이름은 대상 객체와 대상 메서드 이름으로 구성되므로 :to
옵션은 메서드 이름이어야 합니다.
사용자 정의 접두사도 구성할 수 있습니다:
delegate :size, to: :attachment, prefix: :avatar
이전 예에서는 avatar_size
가 생성되었습니다.
:private
옵션은 메서드 범위를 변경합니다:
delegate :date_of_birth, to: :profile, private: true
기본적으로 위임된 메서드는 public입니다. private: true
를 전달하면 이를 변경할 수 있습니다.
주석: active_support/core_ext/module/delegation.rb
에 정의되어 있습니다.
delegate_missing_to
User
객체에서 누락된 모든 것을 Profile
에 위임하고 싶다고 가정해 보겠습니다. delegate_missing_to
매크로를 사용하면 이를 간단하게 구현할 수 있습니다:
class User < ApplicationRecord has_one :profile delegate_missing_to :profile end
대상은 객체 내에서 호출 가능한 것이면 무엇이든 될 수 있습니다. 예를 들어 인스턴스 변수, 메서드, 상수 등입니다. 대상의 public 메서드만 위임됩니다.
주석: active_support/core_ext/module/delegation.rb
에 정의되어 있습니다.
메서드 재정의
때로는 define_method
를 사용하여 메서드를 정의해야 하지만 해당 이름의 메서드가 이미 존재하는지 알 수 없습니다. 존재하는 경우 경고가 발행됩니다. 큰 문제는 아니지만 깨끗하지 않습니다.
redefine_method
메서드는 이러한 잠재적 경고를 방지하고, 필요한 경우 기존 메서드를 제거합니다.
silence_redefinition_of_method
를 사용하면 자신이 대체 메서드를 정의해야 하는 경우(예: delegate
를 사용하는 경우)에도 유용합니다.
주석: active_support/core_ext/module/redefine_method.rb
에 정의되어 있습니다.
클래스 익스텐션
클래스 속성
class_attribute
class_attribute
메서드는 계층 구조 아래에서 재정의될 수 있는 상속 네, 번역을 계속하겠습니다.
class_attribute
메서드는 계층 구조 아래에서 재정의될 수 있는 상속 가능한 클래스 속성을 선언합니다.
class A class_attribute :x end class B < A; end class C < B; end A.x = :a B.x # => :a C.x # => :a B.x = :b A.x # => :a C.x # => :b C.x = :c A.x # => :a B.x # => :b
예를 들어 ActionMailer::Base
는 다음과 같이 정의합니다:
class_attribute :default_params self.default_params = { mime_version: "1.0", charset: "UTF-8", content_type: "text/plain", parts_order: [ "text/plain", "text/enriched", "text/html" ] }.freeze
인스턴스 수준에서도 액세스하고 재정의할 수 있습니다.
A.x = 1 a1 = A.new a2 = A.new a2.x = 2 a1.x # => 1, A에서 온 것 a2.x # => 2, a2에서 재정의된 것
:instance_writer
옵션을 false
로 설정하면 라이터 인스턴스 메서드 생성을 방지할 수 있습니다.
module ActiveRecord class Base class_attribute :table_name_prefix, instance_writer: false, default: "my" end end
모델에서 이 옵션을 사용하면 대량 할당으로부터 속성을 보호할 수 있습니다.
:instance_reader
옵션을 false
로 설정하면 리더 인스턴스 메서드 생성을 방지할 수 있습니다.
class A class_attribute :x, instance_reader: false end A.new.x = 1 A.new.x # NoMethodError
편의를 위해 class_attribute
는 인스턴스 리더의 이중 부정인 인스턴스 술어도 정의합니다. 위의 예에서는 x?
라고 합니다.
:instance_reader
가 false
이면 인스턴스 술어도 NoMethodError
를 반환합니다.
인스턴스 술어를 원하지 않으면 instance_predicate: false
를 전달하면 정의되지 않습니다.
주석: active_support/core_ext/class/attribute.rb
에 정의되어 있습니다.
cattr_reader
, cattr_writer
, 및 cattr_accessor
cattr_reader
, cattr_writer
, cattr_accessor
매크로는 각각의 attr_*
대응물이지만 클래스에 대한 것입니다. 클래스 변수를 nil
로 초기화하고 해당 클래스 메서드를 생성합니다:
class MysqlAdapter < AbstractAdapter # @@emulate_booleans에 대한 클래스 메서드를 생성합니다. cattr_accessor :emulate_booleans end
또한 기본값을 설정하는 블록을 cattr_*
에 전달할 수 있습니다:
class MysqlAdapter < AbstractAdapter # @@emulate_booleans에 대한 클래스 메서드를 생성하고 기본값을 true로 설정합니다. cattr_accessor :emulate_booleans, default: true end
인스턴스 메서드도 생성되지만 클래스 속성에 대한 프록시에 불과합니다. 따라서 인스턴스에서 클래스 속성을 변경할 수 있지만 재정의할 수는 없습니다(class_attribute
와 다름, 위 참조).
:instance_reader
옵션을 false
로 설정하면 리더 인스턴스 메서드 생성을 방지할 수 있고, :instance_writer
옵션을 false
로 설정하면 라이터 인스턴스 메서드 생성을 방지할 수 있습니다. :instance_accessor
옵션을 false
로 설정하면 둘 다 방지할 수 있습니다. 모든 경우에 값은 정확히 false
여야 하며 그 외의 false 값은 허용되지 않습니다.
module A class B # first_name 인스턴스 리더가 생성되지 않습니다. cattr_accessor :first_name, instance_reader: false # last_name= 인스턴스 라이터가 생성되지 않습니다. cattr_accessor :last_name, instance_writer: false # surname 인스턴스 리더 또는 surname= 라이터가 생성되지 않습니다. cattr_accessor :surname, instance_accessor: false end end
모델에서 :instance_accessor
를 false
로 설정하면 대량 할당으로부터 속성을 보호하는 데 유용할 수 있습니다.
주석: active_support/core_ext/module/attribute_accessors.rb
에 정의되어 있습니다.
하위 클래스 및 자손
subclasses
subclasses
메서드는 수신기의 하위 클래스를 반환합니다:
class C; end C.subclasses # => [] class B < C; end C.subclasses # => [B] class A < B; end C.subclasses # => [B] class D < C; end C.subclasses # => [B, D]
이 클래스들이 반환되는 순서는 지정되어 있지 않습니다.
주석: active_support/core_ext/class/subclasses.rb
에 정의되어 있습니다.
descendants
descendants
메서드는 수신기보다 작은 모든 클래스를 반환합니다:
class C; end C.descendants # => [] class B < C; end C.descendants # => [B] class A < B; end C.descendants # => [B, A] class D < C; end C.descendants # => [B, A, D]
이 클래스들이 반환되는 순서는 지정되어 있지 않습니다.
주석: active_support/core_ext/class/subclasses.rb
에 정의되어 있습니다.
문자열 익스텐션
출력 안전성
동기화
데이터를 HTML 템플릿에 삽입하려면 특별한 주의가 필요합니다. 예를 들어 @review.title
을 그대로 삽입할 수는 없습니다. 우선 리뷰 제목이 "Flanagan & Matz rules!"인 경우 출력이 잘못된 HTML이 됩니다. 왜냐하면 앰퍼샌드를 ”&“로 이스케이프해야 하기 때문입니다. 더 중요한 것은 애플리케이션에 따라 이것이 큰 보안 취약점이 될 수 있다는 점입니다. 보안 가이드의 크로스 사이트 스크립팅 섹션을 참조하세요.
안전한 문자열
액티브 서포트에는 (html) 안전 문자열 개념이 있습니다. 안전한 문자열은 HTML에 그대로 삽입할 수 있다고 표시된 문자열입니다. 이는 이스케이프되었는지 여부와 관계없이 신뢰됩니다.
문자열은 기본적으로 안전하지 않습니다:
"".html_safe? # => false
html_safe
메서드를 사용하여 주어진 문자열에서 안전한 문자열을 얻을 수 있습니다:
s = "".html_safe s.html_safe? # => true
html_safe
가 실제로 이스케이프를 수행하지 않는다는 점을 이해하는 것이 중요합니다. 단순히 어설션일 뿐입니다:
s = "<script>...</script>".html_safe s.html_safe? # => true s # => "<script>...</script>"
특정 문자열에 html_safe
를 호출하는 것이 안전한지 확인하는 것은 사용자의 책임입니다.
안전한 문자열에 추가하는 경우, 제자리에서 concat
/<<
로 또는 +
로 추가하든 결과는 안전한 문자열입니다. 안전하지 않은 인수는 이스케이프됩니다:
"".html_safe + "<" # => "<"
안전한 인수는 직접 추가됩니다:
"".html_safe + "<".html_safe # => "<"
이러한 메서드는 일반적인 뷰에서 사용해서는 안 됩니다. 안전하지 않은 값은 자동으로 이스케이프됩니다:
<%= @review.title %> <%# 필요한 경우 이스케이프됩니다 %>
문자열을 그대로 삽입하려면 raw
헬퍼를 사용하세요. html_safe
를 직접 호출하지 마세요:
<%= raw @cms.current_template %> <%# @cms.current_template를 그대로 삽입합니다 %>
또는 <%==
를 사용할 수 있습니다:
<%== @cms.current_template %> <%# @cms.current_template를 그대로 삽입합니다 %>
raw
헬퍼는 내부적으로 html_safe
를 호출합니다:
def raw(stringish) stringish.to_s.html_safe end
주석: active_support/core_ext/string/output_safety.rb
에 정의되어 있습니다.
변환
일반적으로 연결을 제외하고는(위에서 설명한 대로) 문자열을 변경할 수 있는 메서드는 모두 안전하지 않은 문자열을 반환합니다. 이는 downcase
, gsub
, strip
, chomp
, underscore
등입니다.
제자리 변환의 경우 gsub!
와 같이 수신기 자체가 안전하지 않게 됩니다.
정보: 변환이 실제로 무언가를 변경했는지 여부와 관계없이 안전성 비트는 항상 손실됩니다.
변환 및 강제 변환
to_s
를 호출하면 안전한 문자열이 반환되지만, to_str
로 강제 변환하면 안전하지 않은 문자열이 반환됩니다.
복사
dup
또는 clone
을 호출하면 안전한 문자열이 생성됩니다.
remove
remove
메서드는 패턴의 모든 발생을 제거합니다:
"Hello World".remove(/Hello /) # => "World"
파괴적인 버전 String#remove!
도 있습니다.
주석: active_support/core_ext/string/filters.rb
에 정의되어 있습니다.
squish
[squish
][String#squish] 메서드는 선행 및 후행 공백을 제거하고 연속된 공백을 단일 공백으로 대체합니다:
" \n foo\n\r \t bar \n".squish # => "foo bar"
파괴적인 버전 String#squish!
도 있습니다.
ASCII와 유니코드 공백 모두 처리한다는 점에 유의하세요.
주석: active_support/core_ext/string/filters.rb
에 정의되어 있습니다.
[String#squish]: https://api.rubyonrails.org/classes/String.html#method-i네, 번역을 계속하겠습니다.
truncate
truncate
메서드는 지정된 length
이후 문자열의 복사본을 반환합니다:
"Oh dear! Oh dear! I shall be late!".truncate(20) # => "Oh dear! Oh dear!..."
생략 부호는 :omission
옵션으로 사용자 정의할 수 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate(20, omission: "…") # => "Oh dear! Oh …"
특히 생략 문자열의 길이를 고려한다는 점에 유의하세요.
:separator
옵션을 전달하면 자연스러운 구분점에서 문자열을 자를 수 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate(18) # => "Oh dear! Oh dea..." "Oh dear! Oh dear! I shall be late!".truncate(18, separator: " ") # => "Oh dear! Oh..."
:separator
옵션은 정규식일 수도 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate(18, separator: /\s/) # => "Oh dear! Oh..."
위의 예에서 "dear"가 먼저 잘리지만 :separator
로 인해 방지됩니다.
주석: active_support/core_ext/string/filters.rb
에 정의되어 있습니다.
truncate_bytes
truncate_bytes
메서드는 최대 bytesize
바이트로 문자열의 복사본을 반환합니다:
"👍👍👍👍".truncate_bytes(15) # => "👍👍👍…"
생략 부호는 :omission
옵션으로 사용자 정의할 수 있습니다:
"👍👍👍👍".truncate_bytes(15, omission: "🖖") # => "👍👍🖖"
주석: active_support/core_ext/string/filters.rb
에 정의되어 있습니다.
truncate_words
truncate_words
메서드는 지정된 단어 수 이후 문자열의 복사본을 반환합니다:
"Oh dear! Oh dear! I shall be late!".truncate_words(4) # => "Oh dear! Oh dear!..."
생략 부호는 :omission
옵션으로 사용자 정의할 수 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate_words(4, omission: "…") # => "Oh dear! Oh dear!…"
:separator
옵션을 전달하면 자연스러운 구분점에서 문자열을 자를 수 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate_words(3, separator: "!") # => "Oh dear! Oh dear! I shall be late..."
:separator
옵션은 정규식일 수도 있습니다:
"Oh dear! Oh dear! I shall be late!".truncate_words(4, separator: /\s/) # => "Oh dear! Oh dear!..."
주석: active_support/core_ext/string/filters.rb
에 정의되어 있습니다.
inquiry
inquiry
메서드는 문자열을 StringInquirer
객체로 변환하여 등호 검사를 더 쉽게 만듭니다.
"production".inquiry.production? # => true "active".inquiry.inactive? # => false
주석: active_support/core_ext/string/inquiry.rb
에 정의되어 있습니다.
starts_with?
및 ends_with?
액티브 서포트는 String#start_with?
및 String#end_with?
의 3인칭 별칭을 정의합니다:
"foo".starts_with?("f") # => true "foo".ends_with?("o") # => true
주석: active_support/core_ext/string/starts_ends_with.rb
에 정의되어 있습니다.
strip_heredoc
strip_heredoc
메서드는 heredoc의 들여쓰기를 제거합니다.
예를 들어 다음과 같은 경우
if options[:usage] puts <<-USAGE.strip_heredoc This command does such and such. Supported options are: -h This message ... USAGE end
사용자는 왼쪽 여백에 맞춰진 사용법 메시지를 볼 수 있습니다.
기술적으로는 전체 문자열에서 가장 적게 들여쓰인 줄을 찾아 그 양만큼의 선행 공백을 제거합니다.
주석: active_support/core_ext/string/strip.rb
에 정의되어 있습니다.
indent
indent
메서드는 수신기의 줄을 들여씁니다:
<<EOS.indent(2) def some_method some_code end EOS # => def some_method some_code end
두 번째 인수 indent_string
은 사용할 들여쓰기 문자열을 지정합니다. 기본값은 nil
로, 첫 번째 들여쓰인 줄을 보고 추측하고 그렇지 않으면 공백으로 대체합니다.
" foo".indent(2) # => " foo" "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar" "foo".indent(2, "\t") # => "\t\tfoo"
indent_string
은 일반적으로 공백이나 탭이지만 어떤 문자열이든 될 수 있습니다.
세 번째 인수 indent_empty_lines
는 빈 줄도 들여쓰일지 여부를 나타내는 플래그입니다. 기본값은 false입니다.
"foo\n\nbar".indent(2) # => " foo\n\n bar" "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
indent!
메서드는 제자리에서 들여쓰기를 수행합니다.
주석: active_support/core_ext/string/indent.rb
에 정의되어 있습니다.
액세스
at(position)
at
메서드는 문자열의 position
위치에 있는 문자를 반환합니다:
"hello".at(0) # => "h" "hello".at(4) # => "o" "hello".at(-1) # => "o" "hello".at(10) # => nil
주석: active_support/core_ext/string/access.rb
에 정의되어 있습니다.
from(position)
from
메서드는 position
위치부터 시작하는 문자열의 부분 문자열을 반환합니다:
"hello".from(0) # => "hello" "hello".from(2) # => "llo" "hello".from(-2) # => "lo" "hello".from(10) # => nil
주석: active_support/core_ext/string/access.rb
에 정의되어 있습니다.
to(position)
to
메서드는 문자열의 position
위치까지의 부분 문자열을 반환합니다:
"hello".to(0) # => "h" "hello".to(2) # => "hel" "hello".to(-2) # => "hell" "hello".to(10) # => "hello"
주석: active_support/core_ext/string/access.rb
에 정의되어 있습니다.
first(limit = 1)
first
메서드는 문자열의 처음 limit
문자로 이루어진 부분 문자열을 반환합니다.
str.first(n)
호출은 n
> 0이면 str.to(n-1)
과 동등하고, n
== 0이면 빈 문자열을 반환합니다.
주석: active_support/core_ext/string/access.rb
에 정의되어 있습니다.
last(limit = 1)
last
메서드는 문자열의 마지막 limit
문자로 이루어진 부분 문자열을 반환합니다.
str.last(n)
호출은 n
> 0이면 str.from(-n)
과 동등하고, n
== 0이면 빈 문자열을 반환합니다.
주석: active_support/core_ext/string/access.rb
에 정의되어 있습니다.
변형
pluralize
pluralize
메서드는 수신기의 복수형을 반환합니다:
"table".pluralize # => "tables" "ruby".pluralize # => "rubies" "equipment".pluralize # => "equipment"
이전 예에서 보듯이 액티브 서포트는 일부 불규칙 복수형과 불가산 명사를 알고 있습니다. 내장 규칙은 config/initializers/inflections.rb
에서 확장할 수 있습니다. 이 파일은 기본적으로 rails new
명령으로 생성되며 주석에 지침이 있습니다.
pluralize
는 선택적으로 count
매개변수를 받을 수 있습니다. count == 1
이면 단수형이 반환되고, 그 외의 값이면 복수형이 반환됩니다:
"dude".pluralize(0) # => "dudes" "dude".pluralize(1) # => "dude" "dude".pluralize(2) # => "dudes"
액티브 레코드는 이 메서드를 사용하여 모델에 해당하는 기본 테이블 이름을 계산합니다:
# active_record/model_schema.rb def undecorated_table_name(model_name) table_name = model_name.to_s.demodulize.underscore pluralize_table_names ? table_name.pluralize : table_name end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
singularize
singularize
메서드는 pluralize
의 역함수입니다:
"tables".singularize # => "table" "rubies".singularize # => "ruby" "equipment".singularize # => "equipment"
연관관계는 기본 연관 클래스의 이름을 계산할 때 이 메서드를 사용합니다:
# active_record/reflection.rb def derive_class_name class_name = name.to_s.camelize class_name = class_name.singularize if collection? class_name end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
camelize
camelize
메서드는 수신기를 카멜 케이스로 반환합니다:
"product".camelize # => "Product" "admin_user".camelize # => "AdminUser"
일반적으로 이 메서드는 경로를 Ruby 클래스 또는 모듈 이름으로 변환하는 데 사용되며, 슬래시는 네임스페이스를 구분합니다:
"backoffice/session".camelize # => "Backoffice::Session"
예를 들어 액션 팩은 이 메서드를 사용하여 특정 세션 저장소 네, 번역을 계속하겠습니다.
예를 들어 액션 팩은 이 메서드를 사용하여 특정 세션 저장소 클래스를 로드합니다:
# action_controller/metal/session_management.rb def session_store=(store) @@session_store = store.is_a?(Symbol) ? ActionDispatch::Session.const_get(store.to_s.camelize) : store end
camelize
는 선택적으로 :upper
(기본값) 또는 :lower
인수를 받습니다. 후자를 사용하면 첫 번째 문자가 소문자가 됩니다:
"visual_effect".camelize(:lower) # => "visualEffect"
다른 언어의 메서드 이름 규칙을 따르는 경우 유용할 수 있습니다. 예를 들어 JavaScript.
정보: 일반적으로 camelize
는 underscore
의 역함수로 생각할 수 있지만, 그렇지 않은 경우도 있습니다: "SSLError".underscore.camelize
는 "SslError"
를 반환합니다. 이러한 경우를 지원하기 위해 액티브 서포트는 config/initializers/inflections.rb
에서 약어를 지정할 수 있습니다:
ActiveSupport::Inflector.inflections do |inflect| inflect.acronym 'SSL' end "SSLError".underscore.camelize # => "SSLError"
camelize
는 camelcase
의 별칭입니다.
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
underscore
underscore
메서드는 반대 방향으로, 카멜 케이스에서 경로로 변환합니다:
"Product".underscore # => "product" "AdminUser".underscore # => "admin_user"
또한 ”::“를 ”/“로 변환합니다:
"Backoffice::Session".underscore # => "backoffice/session"
그리고 소문자로 시작하는 문자열도 이해합니다:
"visualEffect".underscore # => "visual_effect"
underscore
는 인수를 받지 않습니다.
Rails는 underscore
를 사용하여 컨트롤러 클래스의 소문자 이름을 얻습니다:
# actionpack/lib/abstract_controller/base.rb def controller_path @controller_path ||= name.delete_suffix("Controller").underscore end
예를 들어 이 값은 params[:controller]
에서 얻을 수 있습니다.
정보: 일반적으로 underscore
는 camelize
의 역함수로 생각할 수 있지만, 그렇지 않은 경우도 있습니다. 예를 들어 "SSLError".underscore.camelize
는 "SslError"
를 반환합니다.
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
titleize
titleize
메서드는 수신기의 단어를 대문자로 만듭니다:
"alice in wonderland".titleize # => "Alice In Wonderland" "fermat's enigma".titleize # => "Fermat's Enigma"
titleize
는 titlecase
의 별칭입니다.
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
dasherize
dasherize
메서드는 수신기의 밑줄을 대시로 바꿉니다:
"name".dasherize # => "name" "contact_data".dasherize # => "contact-data"
모델의 XML 직렬화기는 이 메서드를 사용하여 노드 이름에 대시를 사용합니다:
# active_model/serializers/xml.rb def reformat_name(name) name = name.camelize if camelize? dasherize? ? name.dasherize : name end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
demodulize
정규화된 상수 이름이 있는 문자열에서 demodulize
메서드는 가장 오른쪽 부분, 즉 상수 이름 자체를 반환합니다:
"Product".demodulize # => "Product" "Backoffice::UsersController".demodulize # => "UsersController" "Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils" "::Inflections".demodulize # => "Inflections" "".demodulize # => ""
예를 들어 액티브 레코드는 이 메서드를 사용하여 카운터 캐시 열의 이름을 계산합니다:
# active_record/reflection.rb def counter_cache_column if options[:counter_cache] == true "#{active_record.name.demodulize.underscore.pluralize}_count" elsif options[:counter_cache] options[:counter_cache] end end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
deconstantize
정규화된 상수 참조 표현식이 있는 문자열에서 deconstantize
메서드는 가장 오른쪽 부분을 제거하여 일반적으로 상수의 컨테이너 이름을 남깁니다:
"Product".deconstantize # => "" "Backoffice::UsersController".deconstantize # => "Backoffice" "Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
parameterize
parameterize
메서드는 수신기를 예쁜 URL에 사용할 수 있도록 정규화합니다.
"John Smith".parameterize # => "john-smith" "Kurt Gödel".parameterize # => "kurt-godel"
대소문자를 유지하려면 preserve_case
인수를 true로 설정하세요. 기본적으로 preserve_case
는 false입니다.
"John Smith".parameterize(preserve_case: true) # => "John-Smith" "Kurt Gödel".parameterize(preserve_case: true) # => "Kurt-Godel"
사용자 정의 구분자를 사용하려면 separator
인수를 재정의하세요.
"John Smith".parameterize(separator: "_") # => "john_smith" "Kurt Gödel".parameterize(separator: "_") # => "kurt_godel"
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
tableize
tableize
메서드는 underscore
를 pluralize
한 것입니다.
"Person".tableize # => "people" "Invoice".tableize # => "invoices" "InvoiceLine".tableize # => "invoice_lines"
일반적으로 tableize
는 간단한 경우 모델에 해당하는 테이블 이름을 반환합니다. 실제 액티브 레코드 구현은 단순한 tableize
가 아니며, 클래스 이름을 demodulize하고 몇 가지 옵션을 확인합니다.
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
classify
classify
메서드는 tableize
의 역함수입니다. 테이블 이름에 해당하는 클래스 이름을 반환합니다:
"people".classify # => "Person" "invoices".classify # => "Invoice" "invoice_lines".classify # => "InvoiceLine"
이 메서드는 정규화된 테이블 이름도 이해합니다:
"highrise_production.companies".classify # => "Company"
classify
는 문자열 형태의 클래스 이름을 반환한다는 점에 유의하세요. constantize
를 호출하면 실제 클래스 객체를 얻을 수 있습니다.
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
constantize
constantize
메서드는 수신기의 상수 참조 표현식을 해결합니다:
"Integer".constantize # => Integer module M X = 1 end "M::X".constantize # => 1
문자열이 알려진 상수로 평가되지 않거나 내용이 유효한 상수 이름이 아닌 경우 constantize
는 NameError
를 발생시킵니다.
constantize
에 의한 상수 이름 확인은 항상 최상위 Object
에서 시작합니다. 심지어 선행 ”::“이 없어도 마찬가지입니다.
X = :in_Object module M X = :in_M X # => :in_M "::X".constantize # => :in_Object "X".constantize # => :in_Object (!) end
따라서 일반적으로 동일한 위치에서 실제 상수가 평가되는 것과 동일하지 않습니다.
메일러 테스트 케이스는 테스트 클래스의 이름을 사용하여 테스트 중인 메일러를 얻습니다:
# action_mailer/test_case.rb def determine_default_mailer(name) name.delete_suffix("Test").constantize rescue NameError => e raise NonInferrableMailerError.new(name) end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
humanize
humanize
메서드는 사용자에게 표시할 수 있도록 속성 이름을 조정합니다.
구체적으로는 다음과 같은 변환을 수행합니다:
- 인수에 인간 변형 규칙을 적용합니다.
- 선행 밑줄(있는 경우)을 삭제합니다.
- ”_id" 접미사를 제거합니다(있는 경우).
- 밑줄을 공백으로 바꿉니다(있는 경우).
- 두문자어를 제외한 모든 단어를 소문자로 변환합니다.
- 첫 번째 단어를 대문자로 변환합니다.
첫 번째 단어의 대문자화는 :capitalize
옵션을 false로 설정하여 끌 수 있습니다(기본값은 true).
"name".humanize # => "Name" "author_id".humanize # => "Author" "author_id".humanize(capitalize: false) # => "author" "comments_count".humanize # => "Comments count" "_id".humanize # => "Id"
“SSL"이 약어로 정의된 경우:
"ssl_error".humanize # => "SSL error"
헬퍼 메서드 full_messages
는 속성 이름을 포함하기 위해 humanize
를 사용합니다:
def full_messages map { |attribute, message| full_message(attribute, message) } end def full_message # ... attr_name = attribute.to_s.tr(".", "_").humanize attr_name = @base.class.human_attribute_name(attribute, default: attr_name) # ... end
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
String#humanize: https://api.rubyonrails.org/classes/String.html#네, 번역을 계속하겠습니다.
foreign_key
foreign_key
메서드는 클래스 이름에서 외래 키 열 이름을 생성합니다. 이를 위해 demodulize, underscore, ”_id" 접미사를 추가합니다:
"User".foreign_key # => "user_id" "InvoiceLine".foreign_key # => "invoice_line_id" "Admin::Session".foreign_key # => "session_id"
밑줄 없이 “_id"를 원하면 false 인수를 전달하세요:
"User".foreign_key(false) # => "userid"
연관관계는 이 메서드를 사용하여 외래 키를 추론합니다. 예를 들어 has_one
과 has_many
가 이렇게 합니다:
# active_record/associations.rb foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
upcase_first
upcase_first
메서드는 수신기의 첫 번째 문자를 대문자로 만듭니다:
"employee salary".upcase_first # => "Employee salary" "".upcase_first # => ""
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
downcase_first
downcase_first
메서드는 수신기의 첫 번째 문자를 소문자로 변환합니다:
"If I had read Alice in Wonderland".downcase_first # => "if I had read Alice in Wonderland" "".downcase_first # => ""
주석: active_support/core_ext/string/inflections.rb
에 정의되어 있습니다.
변환
to_date
, to_time
, to_datetime
to_date
, to_time
, to_datetime
메서드는 기본적으로 Date._parse
의 편의 래퍼입니다:
"2010-07-27".to_date # => Tue, 27 Jul 2010 "2010-07-27 23:37:00".to_time # => 2010-07-27 23:37:00 +0200 "2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
to_time
은 선택적으로 :utc
또는 :local
인수를 받아 원하는 시간대의 시간을 반환합니다:
"2010-07-27 23:42:00".to_time(:utc) # => 2010-07-27 23:42:00 UTC "2010-07-27 23:42:00".to_time(:local) # => 2010-07-27 23:42:00 +0200
기본값은 :local
입니다.
자세한 내용은 Date._parse
문서를 참조하세요.
정보: 이 세 메서드 모두 빈 수신기에 대해 nil
을 반환합니다.
주석: active_support/core_ext/string/conversions.rb
에 정의되어 있습니다.
기호 익스텐션
starts_with?
및 ends_with?
액티브 서포트는 Symbol#start_with?
및 Symbol#end_with?
의 3인칭 별칭을 정의합니다:
:foo.starts_with?("f") # => true :foo.ends_with?("o") # => true
주석: active_support/core_ext/symbol/starts_ends_with.rb
에 정의되어 있습니다.
숫자 익스텐션
바이트
모든 숫자는 다음 메서드에 응답합니다:
이들은 변환 계수 1024를 사용하여 해당 바이트 수를 반환합니다:
2.kilobytes # => 2048 3.megabytes # => 3145728 3.5.gigabytes # => 3758096384.0 -4.exabytes # => -4611686018427387904
단수형 별칭도 있어 다음과 같이 사용할 수 있습니다:
1.megabyte # => 1048576
주석: active_support/core_ext/numeric/bytes.rb
에 정의되어 있습니다.
시간
다음 메서드:
은 시간 선언과 계산을 가능하게 합니다. 예를 들어 45.minutes + 2.hours + 4.weeks
와 같이 사용할 수 있습니다. 반환 값은 Time 객체에 추가하거나 빼는 데 사용할 수 있습니다.
이 메서드는 from_now
, ago
등과 결합하여 정확한 날짜 계산을 할 수 있습니다. 예:
# Time.current.advance(days: 1)와 동등 1.day.from_now # Time.current.advance(weeks: 2)와 동등 2.weeks.from_now # Time.current.advance(days: 4, weeks: 5)와 동등 (4.days + 5.weeks).from_now
경고. 다른 지속 기간은 Integer
확장을 참조하세요.
주석: active_support/core_ext/numeric/time.rb
에 정의되어 있습니다.
형식화
숫자를 다양한 방식으로 문자열로 표현할 수 있습니다.
전화번호 형식의 숫자 문자열을 생성합니다:
5551234.to_fs(:phone) # => 555-1234 1235551234.to_fs(:phone) # => 123-555-1234 1235551234.to_fs(:phone, area_code: true) # => (123) 555-1234 1235551234.to_fs(:phone, delimiter: " ") # => 123 555 1234 1235551234.to_fs(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555 1235551234.to_fs(:phone, country_code: 1) # => +1-123-555-1234
통화 형식의 숫자 문자열을 생성합니다:
1234567890.50.to_fs(:currency) # => $1,234,567,890.50 1234567890.506.to_fs(:currency) # => $1,234,567,890.51 1234567890.506.to_fs(:currency, precision: 3) # => $1,234,567,890.506
백분율 형식의 숫자 문자열을 생성합니다:
100.to_fs(:percentage) # => 100.000% 100.to_fs(:percentage, precision: 0) # => 100% 1000.to_fs(:percentage, delimiter: ".", separator: ",") # => 1.000,000% 302.24398923423.to_fs(:percentage, precision: 5) # => 302.24399%
구분 기호가 있는 숫자 문자열을 생성합니다:
12345678.to_fs(:delimited) # => 12,345,678 12345678.05.to_fs(:delimited) # => 12,345,678.05 12345678.to_fs(:delimited, delimiter: ".") # => 12.345.678 12345678.to_fs(:delimited, delimiter: ",") # => 12,345,678 12345678.05.to_fs(:delimited, separator: " ") # => 12,345,678 05
지정된 정밀도로 반올림된 숫자 문자열을 생성합니다:
111.2345.to_fs(:rounded) # => 111.235 111.2345.to_fs(:rounded, precision: 2) # => 111.23 13.to_fs(:rounded, precision: 5) # => 13.00000 389.32314.to_fs(:rounded, precision: 0) # => 389 111.2345.to_fs(:rounded, significant: true) # => 111
사람이 읽을 수 있는 바이트 수 형식의 숫자 문자열을 생성합니다:
123.to_fs(:human_size) # => 123 Bytes 1234.to_fs(:human_size) # => 1.21 KB 12345.to_fs(:human_size) # => 12.1 KB 1234567.to_fs(:human_size) # => 1.18 MB 1234567890.to_fs(:human_size) # => 1.15 GB 1234567890123.to_fs(:human_size) # => 1.12 TB 1234567890123456.to_fs(:human_size) # => 1.1 PB 1234567890123456789.to_fs(:human_size) # => 1.07 EB
사람이 읽을 수 있는 단어 형식의 숫자 문자열을 생성합니다:
123.to_fs(:human) # => "123" 1234.to_fs(:human) # => "1.23 Thousand" 12345.to_fs(:human) # => "12.3 Thousand" 1234567.to_fs(:human) # => "1.23 Million" 1234567890.to_fs(:human) # => "1.23 Billion" 1234567890123.to_fs(:human) # => "1.23 Trillion" 1234567890123456.to_fs(:human) # => "1.23 Quadrillion"
주석: active_support/core_ext/numeric/conversions.rb
에 정의되어 있습니다.
정수 익스텐션
multiple_of?
multiple_of?
메서드는 정수가 인수의 배수인지 테스트합니다:
2.multiple_of?(1) # => true 1.multiple_of?(2) # => false
주석: active_support/core_ext/integer/multiple.rb
에 정의되어 있습니다.
ordinal
ordinal
메서드는 수신기 네, 번역을 계속하겠습니다.
ordinal
메서드는 수신기 정수에 해당하는 서수 접미사 문자열을 반환합니다:
1.ordinal # => "st" 2.ordinal # => "nd" 53.ordinal # => "rd" 2009.ordinal # => "th" -21.ordinal # => "st" -134.ordinal # => "th"
주석: active_support/core_ext/integer/inflections.rb
에 정의되어 있습니다.
ordinalize
ordinalize
메서드는 수신기 정수에 해당하는 서수 문자열을 반환합니다. ordinal
메서드와 달리 접미사만 반환하지 않습니다.
1.ordinalize # => "1st" 2.ordinalize # => "2nd" 53.ordinalize # => "53rd" 2009.ordinalize # => "2009th" -21.ordinalize # => "-21st" -134.ordinalize # => "-134th"
주석: active_support/core_ext/integer/inflections.rb
에 정의되어 있습니다.
시간
다음 메서드:
는 시간 선언과 계산을 가능하게 합니다. 예를 들어 4.months + 5.years
와 같이 사용할 수 있습니다. 반환 값은 Time 객체에 추가하거나 빼는 데 사용할 수 있습니다.
이 메서드는 from_now
, ago
등과 결합하여 정확한 날짜 계산을 할 수 있습니다. 예:
# Time.current.advance(months: 1)와 동등 1.month.from_now # Time.current.advance(years: 2)와 동등 2.years.from_now # Time.current.advance(months: 4, years: 5)와 동등 (4.months + 5.years).from_now
경고. 다른 지속 기간은 Numeric
확장을 참조하세요.
주석: active_support/core_ext/integer/time.rb
에 정의되어 있습니다.
BigDecimal 익스텐션
to_s
to_s
메서드는 기본 지정자로 "F"를 제공합니다. 즉, to_s
를 단순히 호출하면 부동 소수점 표현이 반환되며 공학 표기법은 사용되지 않습니다:
BigDecimal(5.00, 6).to_s # => "5.0"
공학 표기법은 여전히 지원됩니다:
BigDecimal(5.00, 6).to_s("e") # => "0.5E1"
Enumerable 익스텐션
index_by
index_by
메서드는 열거형의 요소를 키로 하는 해시를 생성합니다.
블록에 각 요소를 전달하고 반환된 값으로 요소를 인덱싱합니다:
invoices.index_by(&:number) # => {"2009-032" => <Invoice ...>, "2009-008" => <Invoice ...>, ...}
경고. 키는 일반적으로 고유해야 합니다. 블록이 다른 요소에 대해 동일한 값을 반환하면 해당 키에 대한 컬렉션이 구축되지 않습니다. 마지막 항목이 승리합니다.
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
index_with
index_with
메서드는 열거형의 요소를 키로 하는 해시를 생성합니다. 값은 전달된 기본값이거나 블록에서 반환됩니다.
post = Post.new(title: "hey there", body: "what's up?") %i( title body ).index_with { |attr_name| post.public_send(attr_name) } # => { title: "hey there", body: "what's up?" } WEEKDAYS.index_with(Interval.all_day) # => { monday: [ 0, 1440 ], … }
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
many?
many?
메서드는 collection.size > 1
의 단축 표현입니다:
<% if pages.many? %> <%= pagination_links %> <% end %>
선택적 블록이 주어지면 many?
는 해당 요소만 고려합니다:
@see_more = videos.many? { |video| video.category == params[:category] }
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
exclude?
exclude?
술어는 주어진 객체가 컬렉션에 속하지 않는지 테스트합니다. 내장 include?
의 부정입니다:
to_visit << node if visited.exclude?(node)
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
including
including
메서드는 전달된 요소를 포함하는 새 열거형을 반환합니다:
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ] ["David", "Rafael"].including %w[ Aaron Todd ] # => ["David", "Rafael", "Aaron", "Todd"]
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
excluding
excluding
메서드는 지정된 요소를 제외한 열거형의 복사본을 반환합니다.
이는 Enumerable#excluding
의 최적화 버전으로, 성능 향상을 위해 Array#-
를 사용합니다.
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"] [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
excluding
은 without
의 별칭입니다.
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
pluck
pluck
메서드는 각 요소에서 지정된 키를 추출합니다:
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) # => ["David", "Rafael", "Aaron"] [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name) # => [[1, "David"], [2, "Rafael"]]
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
pick
pick
메서드는 첫 번째 요소에서 지정된 키를 추출합니다:
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name) # => "David" [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name) # => [1, "David"]
주석: active_support/core_ext/enumerable.rb
에 정의되어 있습니다.
배열 익스텐션
액세스
액티브 서포트는 배열에 대한 API를 강화하여 특정 방식으로 액세스할 수 있게 합니다. 예를 들어 to
메서드는 전달된 인덱스까지의 하위 배열을 반환합니다:
%w(a b c d).to(2) # => ["a", "b", "c"] [].to(7) # => []
마찬가지로 from
메서드는 전달된 인덱스부터 끝까지의 꼬리 부분을 반환합니다. 인덱스가 배열 길이보다 크면 빈 배열을 반환합니다.
%w(a b c d).from(2) # => ["c", "d"] %w(a b c d).from(10) # => [] [].from(0) # => []
including
메서드는 전달된 요소를 포함하는 새 배열을 반환합니다:
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ] [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
excluding
메서드는 지정된 요소를 제외한 배열의 복사본을 반환합니다.
이는 성능 향상을 위해 Array#-
를 사용하는 Enumerable#excluding
의 최적화 버전입니다.
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"] [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
second
, third
, fourth
, fifth
메서드는 해당 요소를 반환하며, second_to_last
와 third_to_last
도 마찬가지입니다(first
와 last
는 내장). 사회적 지혜와 긍정적인 건설성 덕분에 forty_two
도 사용할 수 있습니다.
%w(a b c d).third # => "c" %w(a b c d).fifth # => nil
주석: active_support/core_ext/array/access.rb
에 정의되어 있습니다.
추출
extract!
메서드는 블록이 true를 반환하는 요소를 제거하고 반환합니다.
블록이 주어지지 않으면 대신 Enumerator가 반환됩니다.
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5,네, 번역을 계속하겠습니다. ```ruby numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9] numbers # => [0, 2, 4, 6, 8]
주석: active_support/core_ext/array/extract.rb
에 정의되어 있습니다.
옵션 추출
메서드 호출에서 마지막 인수가 해시인 경우(&block
인수는 제외), Ruby는 괄호를 생략할 수 있습니다:
User.exists?(email: params[:email])
이러한 구문적 설탕은 위치 인수가 너무 많은 경우 피하기 위해 Rails에서 많이 사용됩니다. 특히 옵션 해시를 사용하는 것이 관용적입니다.
그러나 가변 인수를 받고 선언에 *
를 사용하는 메서드의 경우 이러한 옵션 해시가 인수 배열의 항목이 되어 그 역할을 잃게 됩니다.
이러한 경우 extract_options!
를 사용하여 옵션 해시를 구분할 수 있습니다. 이 메서드는 배열의 마지막 항목이 해시인지 확인하고, 그렇다면 해당 해시를 팝업하여 반환합니다. 그렇지 않으면 빈 해시를 반환합니다.
예를 들어 caches_action
컨트롤러 매크로의 정의를 보겠습니다:
def caches_action(*actions) return unless cache_configured? options = actions.extract_options! # ... end
이 메서드는 임의의 수의 작업 이름과 선택적 옵션 해시를 마지막 인수로 받습니다. extract_options!
호출을 통해 옵션 해시를 얻고 actions
에서 제거할 수 있습니다.
주석: active_support/core_ext/array/extract_options.rb
에 정의되어 있습니다.
변환
to_sentence
to_sentence
메서드는 배열을 항목을 열거하는 문장 형태의 문자열로 변환합니다:
%w().to_sentence # => "" %w(Earth).to_sentence # => "Earth" %w(Earth Wind).to_sentence # => "Earth and Wind" %w(Earth Wind Fire).to_sentence # => "Earth, Wind, and Fire"
이 메서드는 세 가지 옵션을 받습니다:
:two_words_connector
: 길이가 2인 배열에 사용됩니다. 기본값은 ” and “입니다.:words_connector
: 3개 이상의 요소가 있는 배열에서 마지막 두 개를 제외한 요소를 연결하는 데 사용됩니다. 기본값은 ”, “입니다.:last_word_connector
: 3개 이상의 요소가 있는 배열에서 마지막 두 개의 요소를 연결하는 데 사용됩니다. 기본값은 ”, and “입니다.
이 옵션의 기본값은 지역화될 수 있으며, 해당 키는 다음과 같습니다:
옵션 | I18n 키 |
---|---|
:two_words_connector |
support.array.two_words_connector |
:words_connector |
support.array.words_connector |
:last_word_connector |
support.array.last_word_connector |
주석: active_support/core_ext/array/conversions.rb
에 정의되어 있습니다.
to_fs
to_fs
메서드는 기본적으로 to_s
와 동일하게 작동합니다.
그러나 배열에 id
에 응답하는 항목이 포함된 경우 :db
기호를 인수로 전달할 수 있습니다. 이는 일반적으로 Active Record 객체의 컬렉션에 사용됩니다. 반환되는 문자열은 다음과 같습니다:
[].to_fs(:db) # => "null" [user].to_fs(:db) # => "8456" invoice.lines.to_fs(:db) # => "23,567,556,12"
예제의 정수는 각각 id
호출에서 온 것으로 가정됩니다.
주석: active_support/core_ext/array/conversions.rb
에 정의되어 있습니다.
to_xml
to_xml
메서드는 수신기의 XML 표현을 포함하는 문자열을 반환합니다:
Contributor.limit(2).order(:rank).to_xml # => # <?xml version="1.0" encoding="UTF-8"?> # <contributors type="array"> # <contributor> # <id type="integer">4356</id> # <name>Jeremy Kemper</name> # <rank type="integer">1</rank> # <url-id>jeremy-kemper</url-id> # </contributor> # <contributor> # <id type="integer">4404</id> # <name>David Heinemeier Hansson</name> # <rank type="integer">2</rank> # <url-id>david-heinemeier-hansson</url-id> # </contributor> # </contributors>
이를 위해 각 항목에 to_xml
를 보내고 결과를 루트 노드 아래에 수집합니다. 모든 항목은 to_xml
에 응답해야 하며, 그렇지 않으면 예외가 발생합니다.
기본적으로 루트 요소의 이름은 첫 번째 항목의 클래스 이름을 언더스코어와 대시로 변환한 복수형입니다. 단, 나머지 요소가 해당 유형(is_a?
로 확인)에 속하고 해시가 아닌 경우에만 그렇습니다. 위의 예에서는 "contributors"입니다.
요소 중 하나라도 첫 번째 것과 다른 유형이면 루트 노드가 "objects"가 됩니다:
[Contributor.first, Commit.first].to_xml # => # <?xml version="1.0" encoding="UTF-8"?> # <objects type="array"> # <object> # <id type="integer">4583</id> # <name>Aaron Batalion</name> # <rank type="integer">53</rank> # <url-id>aaron-batalion</url-id> # </object> # <object> # <author>Joshua Peek</author> # <authored-timestamp type="datetime">2009-09-02T16:44:36Z</authored-timestamp> # <branch>origin/master</branch> # <committed-timestamp type="datetime">2009-09-02T16:44:36Z</committed-timestamp> # <committer>Joshua Peek</committer> # <git-show nil="true"></git-show> # <id type="integer">190316</id> # <imported-from-svn type="boolean">false</imported-from-svn> # <message>Kill AMo observing wrap_with_notifications since ARes was only using it</message> # <sha1>723a47bfb3708f968821bc969a9a3fc873a3ed58</sha1> # </object> # </objects>
수신기가 해시 배열인 경우 기본적으로 루트 요소도 "objects"입니다:
[{ a: 1, b: 2 }, { c: 3 }].to_xml # => # <?xml version="1.0" encoding="UTF-8"?> # <objects type="array"> # <object> # <b type="integer">2</b> # <a type="integer">1</a> # </object> # <object> # <c type="integer">3</c> # </object> # </objects>
경고. 컬렉션이 비어 있으면 기본적으로 루트 요소는 "nil-classes"가 됩니다. 이는 함정이 될 수 있습니다. 예를 들어 위의 기여자 목록의 루트 요소는 컬렉션이 비어 있으면 "contributors"가 아니라 "nil-classes"가 됩니다. :root
옵션을 사용하여 일관된 루트 요소를 보장할 수 있습니다.
자식 노드의 이름은 기본적으로 루트 노드의 단수형입니다. 위의 예에서는 "contributor"와 "object"를 보았습니다. :children
옵션을 사용하여 이러한 노드 이름을 설정할 수 있습니다.
기본 XML 빌더는 Builder::XmlMarkup
의 새 인스턴스입니다. :builder
옵션을 사용하여 사용자 정의 빌더를 구성할 수 있습니다. 이 메서드는 또한 :dasherize
등의 옵션을 받으며, 이는 빌더에 전달됩니다:
Contributor.limit(2).order(:rank).to_xml(skip_types: true) # => # <?xml version="1.0" encoding="UTF-8"?> # <contributors> # <contributor> # <id>4356</id> # <name>Jeremy Kemper</name> # <rank>1</rank> # <url-id>jeremy-kemper</url-id> # </contributor> # <contributor> # <id>4404</id> # <name>David Heinemeier Hansson</name> # <rank>2</rank> # <url-id>david-heinemeier-hansson</url-id> # </contributor> # </contributors>
주석: active_support/core_ext/array/conversions.rb
에 정의되어 있습니다.
래핑
Array.wrap
메서드는 인수가 이미 배열(또는 배열 유사)이 아닌 경우 인수를 배열로 래핑합니다.
구체적으로:
- 인수가
nil
이면 빈 배열이 반환됩니다. - 그렇지 않고 인수가
to_ary
에 응답하면 해당 값이 호출되고, 반환된 값이nil
이 아니면 해당 값이 반환됩니다. - 그렇지 않으면 인수를 단일 요소로 하는 배열이 반환됩니다.
Array.wrap(nil) # => [] Array.wrap([1, 2, 3]) # => [1, 2, 3] Array.wrap(0) # => [0]
이 메서드는 Kernel#Array
와 유사한 목적이지만 몇 가지 차이점이 있습니다:
- 인수가
to_ary
에 응답하면 해당 메서드가 호출됩니다.Kernel#Array
는 반환된 값이nil
이면to_a
를 시도하지만,Array.wrap
은 즉시 인수를 단일 요소로 하는 배열을 반환합니다. to_ary
에서 반환된 값이nil
도 배열도 아닌 경우Kernel#Array
는 예외를 발생시키지만Array.wrap
은 그렇지 않고 그냥 값을 반환합니다.to_a
를 호출하지 않습니다. 인수가to_ary
에 응답하지 않으면 인수를 단일 요소로 하는 배열을 반환합니다.
마지막 포인트는 일부 열거형에 대해 특히 비교할 만한 가치가 있습니다:
Array.wrap(foo: :bar) # => [{:foo=>:bar}] Array(foo: :bar) # => [[:foo, :bar]]
또한 스플랫 연산자를 사용하는 관련 관용구가 있습니다:
[*object]
주석: active_support/core_ext/array/wrap.rb
에 정의되어 있습니다.
복제
Array#deep_dup
메서드는 Active Support의 Object#deep_dup
메서드를 사용하여 자신과 내부의 모든 객체를 재귀적으로 복제합니다. Array#map
과 같이 작동하지만 네, 번역을 계속하겠습니다.
Array#deep_dup
메서드는 Active Support의 Object#deep_dup
메서드를 사용하여 자신과 내부의 모든 객체를 재귀적으로 복제합니다. Array#map
과 같이 작동하지만 각 객체에 deep_dup
메서드를 보냅니다.
array = [1, [2, 3]] dup = array.deep_dup dup[1][2] = 4 array[1][2] == nil # => true
주석: active_support/core_ext/object/deep_dup.rb
에 정의되어 있습니다.
그룹화
in_groups_of(number, fill_with = nil)
in_groups_of
메서드는 배열을 지정된 크기의 연속 그룹으로 분할합니다. 그룹을 포함하는 배열을 반환합니다:
[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]
또는 블록을 전달하면 차례로 그룹을 생성합니다:
<% sample.in_groups_of(3) do |a, b, c| %> <tr> <td><%= a %></td> <td><%= b %></td> <td><%= c %></td> </tr> <% end %>
첫 번째 예에서는 in_groups_of
가 마지막 그룹을 요청된 크기만큼 nil
로 채웁니다. 두 번째 인수를 사용하여 채우는 값을 변경할 수 있습니다:
[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]]
마지막 그룹을 채우지 않도록 false
를 전달할 수도 있습니다:
[1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
따라서 false
는 채우는 값으로 사용할 수 없습니다.
주석: active_support/core_ext/array/grouping.rb
에 정의되어 있습니다.
in_groups(number, fill_with = nil)
in_groups
메서드는 배열을 지정된 수의 그룹으로 분할합니다. 메서드는 그룹을 포함하는 배열을 반환합니다:
%w(1 2 3 4 5 6 7).in_groups(3) # => [["1", "2", "3"], ["4", "5", nil], ["6", "7", nil]]
또는 블록을 전달하면 차례로 그룹을 생성합니다:
%w(1 2 3 4 5 6 7).in_groups(3) { |group| p group } ["1", "2", "3"] ["4", "5", nil] ["6", "7", nil]
위의 예에서 in_groups
는 필요한 경우 마지막 그룹에 nil
요소를 추가합니다. 그룹은 최대 하나의 이러한 추가 요소를 가질 수 있으며, 항상 마지막 그룹에 있습니다.
두 번째 선택적 인수를 사용하여 채우는 값을 변경할 수 있습니다:
%w(1 2 3 4 5 6 7).in_groups(3, "0") # => [["1", "2", "3"], ["4", "5", "0"], ["6", "7", "0"]]
그리고 false
를 전달하여 더 작은 그룹을 채우지 않도록 할 수 있습니다:
%w(1 2 3 4 5 6 7).in_groups(3, false) # => [["1", "2", "3"], ["4", "5"], ["6", "7"]]
따라서 false
는 채우는 값으로 사용할 수 없습니다.
주석: active_support/core_ext/array/grouping.rb
에 정의되어 있습니다.
split(value = nil)
split
메서드는 구분자로 배열을 나누고 결과 청크를 반환합니다.
블록이 전달되면 블록이 true를 반환하는 요소가 구분자가 됩니다:
(-5..5).to_a.split { |i| i.multiple_of?(4) } # => [[-5], [-3, -2, -1], [1, 2, 3], [5]]
그렇지 않으면 기본값인 nil
을 받은 값이 구분자가 됩니다:
[0, 1, -5, 1, 1, "foo", "bar"].split(1) # => [[0], [-5], [], ["foo", "bar"]]
팁: 이전 예에서 연속된 구분자로 인해 빈 배열이 생성된다는 점에 유의하세요.
주석: active_support/core_ext/array/grouping.rb
에 정의되어 있습니다.
해시 익스텐션
변환
to_xml
to_xml
메서드는 수신기의 XML 표현을 포함하는 문자열을 반환합니다:
{ foo: 1, bar: 2 }.to_xml # => # <?xml version="1.0" encoding="UTF-8"?> # <hash> # <foo type="integer">1</foo> # <bar type="integer">2</bar> # </hash>
이를 위해 메서드는 쌍을 반복하고 값에 따라 노드를 빌드합니다. 키, 값 쌍이 주어지면:
값이 해시인 경우
:root
를 키로 하여 재귀적으로 호출합니다.값이 배열인 경우
:root
를 키로, 키의 단수형을:children
으로 하여 재귀적으로 호출합니다.값이 호출 가능한 객체인 경우 1개 또는 2개의 인수를 받아야 합니다. 인수 수에 따라 호출 가능 객체는
:root
를 키로 하는options
해시와 키의 단수형을 두 번째 인수로 받습니다. 반환 값이 새 노드가 됩니다.값이
to_xml
에 응답하는 경우 메서드가:root
를 키로 호출됩니다.그 외의 경우
key
태그의 노드가 생성되고value
의 문자열 표현이 텍스트 노드가 됩니다.value
가nil
이면 "nil” 속성이 “true"로 추가됩니다.:skip_types
옵션이 존재하고 true가 아닌 경우, 다음 매핑에 따라 "type” 속성도 추가됩니다:
XML_TYPE_NAMES = { "Symbol" => "symbol", "Integer" => "integer", "BigDecimal" => "decimal", "Float" => "float", "TrueClass" => "boolean", "FalseClass" => "boolean", "Date" => "date", "DateTime" => "datetime", "Time" => "datetime" }
기본적으로 루트 노드는 “hash"지만 :root
옵션으로 구성할 수 있습니다.
기본 XML 빌더는 Builder::XmlMarkup
의 새 인스턴스입니다. :builder
옵션을 사용하여 사용자 정의 빌더를 구성할 수 있습니다. 이 메서드는 또한 :dasherize
등의 옵션을 받으며, 이는 빌더에 전달됩니다.
주석: active_support/core_ext/hash/conversions.rb
에 정의되어 있습니다.
병합
Ruby에는 두 해시를 병합하는 내장 메서드 Hash#merge
가 있습니다:
{ a: 1, b: 1 }.merge(a: 0, c: 2) # => {:a=>0, :b=>1, :c=>2}
액티브 서포트는 충돌 시 인수의 해시 키가 승리하는 merge
와 다른 몇 가지 편리한 해시 병합 방법을 정의합니다.
reverse_merge
및 reverse_merge!
충돌 시 인수의 해시 키가 승리하는 merge
와 달리 reverse_merge
를 사용하면 옵션 해시의 기본값을 간단하게 설정할 수 있습니다:
options = options.reverse_merge(length: 30, omission: "...")
그리고 제자리에서 수행하는 reverse_merge!
버전도 있습니다:
options.reverse_merge!(length: 30, omission: "...")
경고. reverse_merge!
는 호출자의 해시를 변경할 수 있으므로 좋은 생각이 아닐 수 있습니다.
주석: active_support/core_ext/hash/reverse_merge.rb
에 정의되어 있습니다.
reverse_update
reverse_update
메서드는 reverse_merge!
의 별칭입니다.
경고. reverse_update
에는 뱅 접미사가 없다는 점에 유의하세요.
주석: active_support/core_ext/hash/reverse_merge.rb
에 정의되어 있습니다.
deep_merge
및 deep_merge!
이전 예에서 볼 수 있듯이 키가 두 해시에 모두 있는 경우 인수의 값이 승리합니다.
액티브 서포트는 Hash#deep_merge
를 정의합니다. 깊은 병합에서는 키가 두 해시에 모두 있고 해당 값도 해시인 경우 해당 병합이 결과 해시의 값이 됩니다:
{ a: { b: 1 } }.deep_merge(a: { c: 2 }) # => {:a=>{:b=>1, :c=>2}}
deep_merge!
메서드는 제자리에서 깊은 병합을 수행합니다.
주석: active_support/core_ext/hash/deep_merge.rb
에 정의되어 있습니다.
깊은 복제
Hash#deep_dup
메서드는 Active Support의 Object#deep_dup
메서드를 사용하여 자신과 모든 키와 값을 재귀적으로 복제합니다. Enumerator#each_with_object
와 같이 작동하지만 내부의 각 쌍에 deep_dup
메서드를 보냅니다.
hash = { a: 1, b: { c: 2, d: [3, 4] } } dup = hash.deep_dup dup[:b][:e] = 5 dup[:b][:d] << 5 hash[:b][:e] == nil # => true hash[:b][:d] == [3, 4] # => true
주석: active_support/core_ext/object/deep_dup.rb
에 정의되어 있습니다.
키 작업
except
및 except!
except
메서드는 인수 목록에 있는 키를 제거한 해시를 반환합니다(있는 경우):
{ a: 1, b: 2 }.except(:a) # => {:b=>2}
수신기가 convert_key
에 응답하는 경우 각 인수에 대해 해당 메서드가 호출네, 번역을 계속하겠습니다.
except
메서드는 인수 목록에 있는 키를 제거한 해시를 반환합니다(있는 경우):
{ a: 1, b: 2 }.except(:a) # => {:b=>2}
수신기가 convert_key
에 응답하는 경우 각 인수에 대해 해당 메서드가 호출됩니다. 이를 통해 예를 들어 인디퍼런트 액세스 해시와 함께 사용할 수 있습니다:
{ a: 1 }.with_indifferent_access.except(:a) # => {} { a: 1 }.with_indifferent_access.except("a") # => {}
제자리에서 키를 제거하는 뱅 버전 except!
도 있습니다.
주석: active_support/core_ext/hash/except.rb
에 정의되어 있습니다.
stringify_keys
및 stringify_keys!
stringify_keys
메서드는 수신기의 키를 문자열로 변환한 새 해시를 반환합니다. 이를 위해 각 키에 to_s
를 보냅니다:
{ nil => nil, 1 => 1, a: :a }.stringify_keys # => {"" => nil, "1" => 1, "a" => :a}
키 충돌의 경우 가장 최근에 삽입된 값이 유지됩니다:
{ "a" => 1, a: 2 }.stringify_keys # 결과는 # => {"a"=>2}
이 메서드는 예를 들어 기호와 문자열을 모두 옵션으로 허용하는 데 유용할 수 있습니다. 예를 들어 ActionView::Helpers::FormHelper
는 다음과 같이 정의합니다:
def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0") options = options.stringify_keys options["type"] = "checkbox" # ... end
두 번째 줄에서 "type” 키에 안전하게 액세스할 수 있으며, 사용자가 :type
또는 “type"을 전달할 수 있습니다.
제자리에서 키를 문자열로 변환하는 뱅 버전 stringify_keys!
도 있습니다.
또한 deep_stringify_keys
와 deep_stringify_keys!
를 사용하여 주어진 해시와 그 안의 모든 해시의 모든 키를 문자열로 변환할 수 있습니다. 결과의 예는 다음과 같습니다:
{ nil => nil, 1 => 1, nested: { a: 3, 5 => 5 } }.deep_stringify_keys # => {""=>nil, "1"=>1, "nested"=>{"a"=>3, "5"=>5}}
주석: active_support/core_ext/hash/keys.rb
에 정의되어 있습니다.
symbolize_keys
및 symbolize_keys!
symbolize_keys
메서드는 가능한 경우 수신기의 키를 기호로 변환한 새 해시를 반환합니다. 이를 위해 각 키에 to_sym
을 보냅니다:
{ nil => nil, 1 => 1, "a" => "a" }.symbolize_keys # => {nil=>nil, 1=>1, :a=>"a"}
경고. 이전 예에서 하나의 키만 기호화되었다는 점에 유의하세요.
키 충돌의 경우 가장 최근에 삽입된 값이 유지됩니다:
{ "a" => 1, a: 2 }.symbolize_keys # => {:a=>2}
이 메서드는 예를 들어 기호와 문자열을 모두 옵션으로 허용하는 데 유용할 수 있습니다. 예를 들어 ActionText::TagHelper
는 다음과 같이 정의합니다:
def rich_text_area_tag(name, value = nil, options = {}) options = options.symbolize_keys options[:input] ||= "trix_input_#{ActionText::TagHelper.id += 1}" # ... end
세 번째 줄에서 :input
키에 안전하게 액세스할 수 있으며, 사용자가 :input
또는 "input"을 전달할 수 있습니다.
제자리에서 키를 기호화하는 뱅 버전 symbolize_keys!
도 있습니다.
또한 deep_symbolize_keys
와 deep_symbolize_keys!
를 사용하여 주어진 해시와 그 안의 모든 해시의 모든 키를 기호화할 수 있습니다. 결과의 예는 다음과 같습니다:
{ nil => nil, 1 => 1, "nested" => { "a" => 3, 5 => 5 } }.deep_symbolize_keys # => {nil=>nil, 1=>1, nested:{a:3, 5=>5}}
주석: active_support/core_ext/hash/keys.rb
에 정의되어 있습니다.
to_options
및 to_options!
to_options
및 to_options!
메서드는 각각 symbolize_keys
및 symbolize_keys!
의 별칭입니다.
주석: active_support/core_ext/hash/keys.rb
에 정의되어 있습니다.
assert_valid_keys
assert_valid_keys
메서드는 임의의 수의 인수를 받고, 수신기에 해당 목록 외의 키가 있는지 확인합니다. 있는 경우 ArgumentError
가 발생합니다.
{ a: 1 }.assert_valid_keys(:a) # 통과 { a: 1 }.assert_valid_keys("a") # ArgumentError
액티브 레코드는 연관관계를 빌드할 때 알 수 없는 옵션을 허용하지 않습니다. 이 제어는 assert_valid_keys
를 통해 구현됩니다.
주석: active_support/core_ext/hash/keys.rb
에 정의되어 있습니다.
값 작업
deep_transform_values
및 deep_transform_values!
deep_transform_values
메서드는 블록 연산을 통해 모든 값을 변환한 새 해시를 반환합니다. 이는 루트 해시와 중첩된 해시 및 배열의 값을 모두 포함합니다.
hash = { person: { name: "Rob", age: "28" } } hash.deep_transform_values { |value| value.to_s.upcase } # => {person: {name: "ROB", age: "28"}}
제자리에서 블록 연산을 사용하여 모든 값을 변환하는 뱅 버전 deep_transform_values!
도 있습니다.
주석: active_support/core_ext/hash/deep_transform_values.rb
에 정의되어 있습니다.
슬라이싱
slice!
메서드는 지정된 키만 남기고 나머지 키/값 쌍을 제거한 후 제거된 쌍을 포함하는 해시를 반환합니다.
hash = { a: 1, b: 2 } rest = hash.slice!(:a) # => {:b=>2} hash # => {:a=>1}
주석: active_support/core_ext/hash/slice.rb
에 정의되어 있습니다.
추출
extract!
메서드는 지정된 키에 해당하는 키/값 쌍을 제거하고 반환합니다.
hash = { a: 1, b: 2 } rest = hash.extract!(:a) # => {:a=>1} hash # => {:b=>2}
extract!
메서드는 수신기와 동일한 해시 하위 클래스를 반환합니다.
hash = { a: 1, b: 2 }.with_indifferent_access rest = hash.extract!(:a).class # => ActiveSupport::HashWithIndifferentAccess
주석: active_support/core_ext/hash/slice.rb
에 정의되어 있습니다.
인디퍼런트 액세스
with_indifferent_access
메서드는 수신기에서 ActiveSupport::HashWithIndifferentAccess
를 반환합니다:
{ a: 1 }.with_indifferent_access["a"] # => 1
주석: active_support/core_ext/hash/indifferent_access.rb
에 정의되어 있습니다.
정규식 익스텐션
multiline?
multiline?
메서드는 정규식에 /m
플래그가 설정되어 있는지, 즉 점이 줄바꿈 문자를 일치시키는지 말합니다.
%r{.}.multiline? # => false %r{.}m.multiline? # => true Regexp.new(".").multiline? # => false Regexp.new(".", Regexp::MULTILINE).multiline? # => true
Rails는 이 메서드를 한 곳에서만 사용합니다. 라우팅 코드에서도 마찬가지입니다. 다중 행 정규식은 라우팅 요구 사항에 허용되지 않으며, 이 플래그를 사용하여 이 제약 조건을 적용합니다.
def verify_regexp_requirements(requirements) # ... if requirement.multiline? raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}" end # ... end
주석: active_support/core_ext/regexp.rb
에 정의되어 있습니다.
범위 익스텐션
to_fs
액티브 서포트는 Range#to_fs
를 to_s
의 대안으로 정의하며, 선택적 형식 인수를 이해합니다. 현재로서는 :db
만 지원됩니다:
(Date.today..Date.tomorrow).to_fs # => "2009-10-25..2009-10-26" (Date.today..Date.tomorrow).to_fs(:db) # => "BETWEEN '2009-10-25' AND '2009-10-26네, 번역을 계속하겠습니다. (Date.today..Date.tomorrow).to_fs(:db) # => "BETWEEN '2009-10-25' AND '2009-10-26'"
예에서 보듯이 :db
형식은 BETWEEN
SQL 절을 생성합니다. 이는 범위 값 조건에 대한 Active Record의 지원에 사용됩니다.
주석: active_support/core_ext/range/conversions.rb
에 정의되어 있습니다.
===
및 include?
Range#===
및 Range#include?
메서드는 주어진 인스턴스의 끝점 사이에 어떤 값이 속하는지 말합니다:
(2..3).include?(Math::E) # => true
액티브 서포트는 이 메서드를 확장하여 인수가 다른 범위일 수 있도록 합니다. 이 경우 인수 범위의 끝점이 수신기 자체에 속하는지 테스트합니다:
(1..10) === (3..7) # => true (1..10) === (0..7) # => false (1..10) === (3..11) # => false (1...9) === (3..9) # => false (1..10).include?(3..7) # => true (1..10).include?(0..7) # => false (1..10).include?(3..11) # => false (1...9).include?(3..9) # => false
주석: active_support/core_ext/range/compare_range.rb
에 정의되어 있습니다.
overlap?
Range#overlap?
메서드는 두 범위가 겹치는지 말합니다:
(1..10).overlap?(7..11) # => true (1..10).overlap?(0..7) # => true (1..10).overlap?(11..27) # => false
주석: active_support/core_ext/range/overlap.rb
에 정의되어 있습니다.
날짜 익스텐션
계산
정보: 다음 계산 메서드에는 1582년 10월의 엣지 케이스가 있습니다. 5일부터 14일까지의 날짜가 존재하지 않기 때문입니다. 이 가이드에서는 간단히 설명하기 위해 이 동작을 문서화하지 않습니다. 즉, Date.new(1582, 10, 4).tomorrow
는 Date.new(1582, 10, 15)
를 반환합니다. Active Support 테스트 스위트의 test/core_ext/date_ext_test.rb
를 확인하여 예상 동작을 확인하세요.
Date.current
액티브 서포트는 Date.current
를 현재 시간대의 오늘 날짜로 정의합니다. 이는 Date.today
와 같지만 사용자 시간대를 고려합니다. 또한 Date.yesterday
와 Date.tomorrow
를 정의하고, past?
, today?
, tomorrow?
, next_day?
, yesterday?
, prev_day?
, future?
, on_weekday?
및 on_weekend?
인스턴스 술어를 정의하며, 이 모두는 Date.current
를 기준으로 합니다.
사용자 시간대를 고려하는 날짜 비교 메서드를 사용할 때는 Date.today
가 아닌 Date.current
를 사용해야 합니다. 사용자 시간대가 시스템 시간대보다 미래일 수 있기 때문에 Date.today
가 Date.yesterday
와 같을 수 있습니다.
주석: active_support/core_ext/date/calculations.rb
에 정의되어 있습니다.
명명된 날짜
beginning_of_week
, end_of_week
beginning_of_week
및 end_of_week
메서드는 각각 주의 시작과 끝 날짜를 반환합니다. 주는 월요일부터 시작하는 것으로 가정되지만, 인수를 전달하거나 스레드 로컬 Date.beginning_of_week
또는 config.beginning_of_week
을 설정하여 변경할 수 있습니다.
d = Date.new(2010, 5, 8) # => Sat, 08 May 2010 d.beginning_of_week # => Mon, 03 May 2010 d.beginning_of_week(:sunday) # => Sun, 02 May 2010 d.end_of_week # => Sun, 09 May 2010 d.end_of_week(:sunday) # => Sat, 08 May 2010
beginning_of_week
는 at_beginning_of_week
의 별칭이고, end_of_week
는 at_end_of_week
의 별칭입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
monday
, sunday
monday
및 sunday
메서드는 각각 이전 월요일과 다음 일요일의 날짜를 반환합니다.
d = Date.new(2010, 5, 8) # => Sat, 08 May 2010 d.monday # => Mon, 03 May 2010 d.sunday # => Sun, 09 May 2010 d = Date.new(2012, 9, 10) # => Mon, 10 Sep 2012 d.monday # => Mon, 10 Sep 2012 d = Date.new(2012, 9, 16) # => Sun, 16 Sep 2012 d.sunday # => Sun, 16 Sep 2012
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
prev_week
, next_week
next_week
메서드는 영어 요일 이름(기본값은 스레드 로컬 Date.beginning_of_week
또는 config.beginning_of_week
, 또는 :monday
)을 받고 해당 요일의 날짜를 반환합니다.
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010 d.next_week # => Mon, 10 May 2010 d.next_week(:saturday) # => Sat, 15 May 2010
prev_week
메서드는 이와 유사합니다:
d.prev_week # => Mon, 26 Apr 2010 d.prev_week(:saturday) # => Sat, 01 May 2010 d.prev_week(:friday) # => Fri, 30 Apr 2010
prev_week
는 last_week
의 별칭입니다.
next_week
와 prev_week
는 Date.beginning_of_week
또는 config.beginning_of_week
가 설정된 경우에도 예상대로 작동합니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
beginning_of_month
, end_of_month
beginning_of_month
및 end_of_month
메서드는 각각 월의 시작과 끝 날짜를 반환합니다:
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010 d.beginning_of_month # => Sat, 01 May 2010 d.end_of_month # => Mon, 31 May 2010
beginning_of_month
는 at_beginning_of_month
의 별칭이고, end_of_month
는 at_end_of_month
의 별칭입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
quarter
, beginning_of_quarter
, end_of_quarter
quarter
메서드는 수신기의 회계 연도 분기를 반환합니다:
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010 d.quarter # => 2
beginning_of_quarter
및 end_of_quarter
메서드는 수신기의 회계 연도 분기의 시작과 끝 날짜를 반환합니다:
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010 d.beginning_of_quarter # => Thu, 01 Apr 2010 d.end_of_quarter # => Wed, 30 Jun 2010
beginning_of_quarter
는 at_beginning_of_quarter
의 별칭이고, end_of_quarter
는 at_end_of_quarter
의 별칭입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
[DateAndTime::Calculations#at_beginning네, 번역을 계속하겠습니다.
beginning_of_year
, end_of_year
beginning_of_year
및 end_of_year
메서드는 각각 연도의 시작과 끝 날짜를 반환합니다:
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010 d.beginning_of_year # => Fri, 01 Jan 2010 d.end_of_year # => Fri, 31 Dec 2010
beginning_of_year
는 at_beginning_of_year
의 별칭이고, end_of_year
는 at_end_of_year
의 별칭입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
기타 날짜 계산
years_ago
, years_since
years_ago
메서드는 지정된 년 수만큼 이전의 날짜를 반환합니다:
date = Date.new(2010, 6, 7) date.years_ago(10) # => Wed, 07 Jun 2000
years_since
는 미래로 이동합니다:
date = Date.new(2010, 6, 7) date.years_since(10) # => Sun, 07 Jun 2020
그러한 날짜가 존재하지 않는 경우 해당 월의 마지막 날짜가 반환됩니다:
Date.new(2012, 2, 29).years_ago(3) # => Sat, 28 Feb 2009 Date.new(2012, 2, 29).years_since(3) # => Sat, 28 Feb 2015
last_year
은 #years_ago(1)
의 단축 표현입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
months_ago
, months_since
months_ago
및 months_since
메서드는 월에 대해 유사하게 작동합니다:
Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010 Date.new(2010, 4, 30).months_since(2) # => Wed, 30 Jun 2010
그러한 날짜가 존재하지 않는 경우 해당 월의 마지막 날짜가 반환됩니다:
Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010 Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
last_month
은 #months_ago(1)
의 단축 표현입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
weeks_ago
, weeks_since
weeks_ago
및 [weeks_since
][DateAndTime::Calculations#week_since] 메서드는 주에 대해 유사하게 작동합니다:
Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010 Date.new(2010, 5, 24).weeks_since(2) # => Mon, 07 Jun 2010
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
advance
날짜를 다른 날짜로 이동하는 가장 일반적인 방법은 advance
입니다. 이 메서드는 :years
, :months
, :weeks
, :days
키가 있는 해시를 받고 해당 키에 지정된 만큼 날짜를 이동한 결과를 반환합니다:
date = Date.new(2010, 6, 6) date.advance(years: 1, weeks: 2) # => Mon, 20 Jun 2011 date.advance(months: 2, days: -2) # => Wed, 04 Aug 2010
이전 예에서 증가량이 음수일 수 있다는 점에 유의하세요.
주석: active_support/core_ext/date/calculations.rb
에 정의되어 있습니다.
구성 요소 변경
change
메서드를 사용하면 수신기와 동일하지만 지정된 연도, 월 또는 일만 다른 새 날짜를 얻을 수 있습니다:
Date.new(2010, 12, 23).change(year: 2011, month: 11) # => Wed, 23 Nov 2011
이 메서드는 존재하지 않는 날짜에 대해 관용적이지 않습니다. 변경이 잘못된 경우 ArgumentError
가 발생합니다:
Date.new(2010, 1, 31).change(month: 2) # => ArgumentError: invalid date
주석: active_support/core_ext/date/calculations.rb
에 정의되어 있습니다.
지속 기간
Duration
객체를 날짜에 추가하거나 빼는 것이 가능합니다:
d = Date.current # => Mon, 09 Aug 2010 d + 1.year # => Tue, 09 Aug 2011 d - 3.hours # => Sun, 08 Aug 2010 21:00:00 UTC +00:00
이는 since
또는 advance
호출로 변환됩니다. 예를 들어 여기서는 달력 개혁에 맞는 점프를 얻습니다:
Date.new(1582, 10, 4) + 1.day # => Fri, 15 Oct 1582
타임스탬프
정보: 다음 메서드는 가능하면 Time
객체를 반환하고, 그렇지 않으면 DateTime
을 반환합니다. 설정된 경우 사용자 시간대를 고려합니다.
beginning_of_day
, end_of_day
beginning_of_day
메서드는 하루의 시작(00:00:00)에 해당하는 타임스탬프를 반환합니다:
date = Date.new(2010, 6, 7) date.beginning_of_day # => Mon Jun 07 00:00:00 +0200 2010
end_of_day
메서드는 하루의 끝(23:59:59)에 해당하는 타임스탬프를 반환합니다:
date = Date.new(2010, 6, 7) date.end_of_day # => Mon Jun 07 23:59:59 +0200 2010
beginning_of_day
는 at_beginning_of_day
, midnight
, at_midnight
의 별칭입니다.
주석: active_support/core_ext/date/calculations.rb
에 정의되어 있습니다.
beginning_of_hour
, end_of_hour
beginning_of_hour
메서드는 시간의 시작(hh:00:00)에 해당하는 타임스탬프를 반환합니다:
date = DateTime.new(2010, 6, 7, 19, 55, 25) date.beginning_of_hour # => Mon Jun 07 19:00:00 +0200 2010
end_of_hour
메서드는 시간의 끝(hh:59:59)에 해당하는 타임스탬프를 반환합니다:
date = DateTime.new(2010, 6, 7, 19, 55, 25) date.end_of_hour # => Mon Jun 07 19:59:59 +0200 2010
beginning_of_hour
는 at_beginning_of_hour
의 별칭입니다.
정보: beginning_of_hour
, end_of_hour
, beginning_of_minute
, end_of_minute
은 Time
과 DateTime
에 구현되어 있지만 Date
에는 없습니다. 시간이나 분에 대한 시작이나 끝은 Date
인스턴스에 의미가 없기 때문입니다.
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
beginning_of_minute
, end_of_minute
beginning_of_minute
메서드는 분의 시작(hh:mm:00)에 해당하는 타임스탬프를 반환합니다:
date = DateTime.new(2010, 6, 7, 19, 55, 25) date.beginning_of_minute # => Mon Jun 07 19:55:00 +0200 2010
end_of_minute
메서드는 분의 끝(hh:mm:59)에 해당하는 타임스탬프를 반환합니다:
date = DateTime.new(2010, 6, 7, 19, 55, 25) date.end_of_minute # => Mon Jun 07 19:55:59네, 번역을 계속하겠습니다. [DateTime#end_of_minute] # => Mon Jun 07 19:55:59 +0200 2010
beginning_of_minute
는 at_beginning_of_minute
의 별칭입니다.
정보: beginning_of_hour
, end_of_hour
, beginning_of_minute
, end_of_minute
은 Time
과 DateTime
에 구현되어 있지만 Date
에는 없습니다. 시간이나 분에 대한 시작이나 끝은 Date
인스턴스에 의미가 없기 때문입니다.
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
ago
, since
ago
메서드는 초 단위의 인수를 받고 그만큼 이전의 자정 시간을 반환합니다:
date = Date.current # => Fri, 11 Jun 2010 date.ago(1) # => Thu, 10 Jun 2010 23:59:59 EDT -04:00
마찬가지로 since
는 미래로 이동합니다:
date = Date.current # => Fri, 11 Jun 2010 date.since(1) # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
주석: active_support/core_ext/date/calculations.rb
에 정의되어 있습니다.
DateTime 익스텐션
경고: DateTime
은 DST 규칙을 인식하지 않으므로 이러한 메서드 중 일부에는 DST 변경이 진행 중일 때 엣지 케이스가 있습니다. 예를 들어 seconds_since_midnight
은 그런 날에 실제 양을 반환하지 않을 수 있습니다.
계산
DateTime
클래스는 Date
의 하위 클래스이므로 active_support/core_ext/date/calculations.rb
를 로드하면 이러한 메서드와 별칭을 상속받지만, 항상 DateTime을 반환합니다.
다음 메서드는 재구현되므로 active_support/core_ext/date/calculations.rb
를 로드할 필요가 없습니다:
한편 advance
와 change
도 정의되어 있으며 더 많은 옵션을 지원합니다. 이들은 아래에 문서화되어 있습니다.
다음 메서드는 active_support/core_ext/date_time/calculations.rb
에만 구현되어 있으며, DateTime 인스턴스에서만 의미가 있습니다:
명명된 DateTime
DateTime.current
액티브 서포트는 DateTime.current
를 Time.now.to_datetime
과 같지만, 사용자 시간대를 고려한다는 점에서 다릅니다. 인스턴스 술어 past?
및 future?
는 DateTime.current
를 기준으로 합니다.
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
기타 익스텐션
seconds_since_midnight
seconds_since_midnight
메서드는 자정 이후 경과된 초 수를 반환합니다:
now = DateTime.current # => Mon, 07 Jun 2010 20:26:36 +0000 now.seconds_since_midnight # => 73596
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
utc
utc
메서드는 수신기와 동일한 DateTime을 UTC로 반환합니다.
now = DateTime.current # => Mon, 07 Jun 2010 19:27:52 -0400 now.utc # => Mon, 07 Jun 2010 23:27:52 +0000
이 메서드는 getutc
의 별칭으로도 사용됩니다.
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
utc?
utc?
술어는 수신기의 시간대가 UTC인지 말합니다:
now = DateTime.now # => Mon, 07 Jun 2010 19:30:47 -0400 now.utc? # => false now.utc.utc? # => true
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
advance
DateTime을 다른 DateTime으로 이동하는 가장 일반적인 방법은 advance
입니다. 이 메서드는 :years
, :months
, :weeks
, :days
, :hours
, :minutes
, :seconds
키가 있는 해시를 받고 해당 키에 지정된 만큼 DateTime을 이동한 결과를 반환합니다.
d = DateTime.current # => Thu, 05 Aug 2010 11:33:31 +0000 d.advance(years: 1, months: 1, days: 1, hours: 1, minutes: 1, seconds: 1) # => Tue, 06 Sep 2011 12:34:32 +0000
이 메서드는 먼저 :years
, :months
, :weeks
, :days
를 사용하여 Date#advance
에 정의된 대로 날짜 부분을 계산합니다. 그 다음 since
를 호출하여 초 단위로 시간을 조정합니다. 이 순서는 중요합니다. 순서가 다르면 일부 엣지 케이스에서 다른 DateTime이 계산됩니다. 위의 Date#advance
예제가 적용되며, 시간 부분과 관련하여 확장할 수 있습니다.
먼저 날짜 부분(처리 순서도 상대적)을 이동하고 나서 시간 부분을 이동하면 다음과 같은 계산이 이루어집니다:
d = DateTime.new(2010, 2, 28, 23, 59, 59) # => Sun, 28 Feb 2010 23:59:59 +0000 d.advance(months: 1, seconds: 1) # => Mon, 29 Mar 2010 00:00:00 +0000
그러나 반대로 계산하면 결과가 다릅니다:
d.advance(seconds: 1).advance(months: 1) # => Thu, 01 Apr 2010 00:00:00 +0000
경고: DateTime
은 DST에 대해 인식하지 않으므로 존재하지 않는 시점으로 이동할 수 있으며, 경고나 오류 없이 그렇게 됩니다.
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
구성 요소 변경
change
메서드를 사용하면 수신기와 동일하지만 :year
, :month
, :day
, :hour
, :min
, :sec
, :offset
, :start
옵션으로 지정된 값이 다른 새 DateTime을 얻을 수 있습니다:
now = DateTime.current # => Tue, 08 Jun 2010 01:56:22 +0000 now.change(year: 2011, offset: Rational(-6, 24)) # => Wed, 08 Jun 2011 01:56:22 -0600
시간이 0으로 설정되면 분과 초도 0이 됩니다(값이 주어진 경우는 제외):
now.change(hour: 0) # => Tue, 08 Jun 2010 00:00:00 +0000
마찬가지로 분이 0으로 설정되면 초도 0이 됩니다(값이 주어진 경우는 제외):
now.change(min: 0) # => Tue, 08 Jun 2010 01:00:00 +0000
이 메서드는 존재하지 않는 날짜에 대해 관용적이지 않습니다. 변경이 잘못된 경우 ArgumentError
가 발생합니다:
DateTime.current.change(month: 2, day: 30) # => ArgumentError: invalid date
주석: active_support/core_ext/date_time/calculations.rb
에 정의되어 있습니다.
지속 기간
Duration
객체를 DateTime에 추가하거나 빼는 것이 가능합니다:
now = DateTime.current # => Mon, 09 Aug 2010 23:15:17 +0000 now + 1.year # => Tue, 09 Aug 2011 23:15:17 +0000 now - 1.week # => Mon, 02 Aug 2010 23:15:17 +0000
이는 since
또는 advance
호출로 변환됩니다. 예를 들어 여기서는 달력 개혁에 맞는 점프를 얻습니다:
DateTime.new(1582, 10, 4, 23) + 1.hour # => Fri, 15 Oct 1582 00:00:00 +0000
Time 익스텐션
계산
이들은 유사합니다. 위의 문서를 참조하고 다음과 같은 차이점을 고려하세요:
change
는 추가적으로:usec
옵션을 받습니다.Time
은 DST를 이해하므로 다음과 같이 올바른 DST 계산을 수행합니다.
Time.zone_default # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...> # 바르셀로나에서 2010/03/28 02:00 +0100은 DST로 인해 2010/03/28 03:00 +0200가 됩니다네, 번역을 계속하겠습니다. # 바르셀로나에서 2010/03/28 02:00 +0100은 DST로 인해 2010/03/28 03:00 +0200가 됩니다. t = Time.local(2010, 3, 28, 1, 59, 59) # => Sun Mar 28 01:59:59 +0100 2010 t.advance(seconds: 1) # => Sun Mar 28 03:00:00 +0200 2010
Time.current
액티브 서포트는 Time.current
를 현재 시간대의 오늘 날짜로 정의합니다. 이는 Time.now
와 같지만, 사용자 시간대를 고려합니다. 또한 인스턴스 술어 past?
, today?
, tomorrow?
, next_day?
, yesterday?
, prev_day?
및 future?
를 정의하며, 이 모두는 Time.current
를 기준으로 합니다.
사용자 시간대를 고려하는 Time 비교 메서드를 사용할 때는 Time.now
가 아닌 Time.current
를 사용해야 합니다. 사용자 시간대가 시스템 시간대보다 미래일 수 있기 때문에 Time.now.to_date
가 Date.yesterday
와 같을 수 있습니다.
주석: active_support/core_ext/time/calculations.rb
에 정의되어 있습니다.
all_day
, all_week
, all_month
, all_quarter
, 및 all_year
all_day
메서드는 현재 시간의 하루 전체를 나타내는 범위를 반환합니다.
now = Time.current # => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_day # => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
마찬가지로 all_week
, all_month
, all_quarter
및 all_year
는 시간 범위를 생성하는 목적을 serve합니다.
now = Time.current # => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_week # => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00 now.all_week(:sunday) # => Sun, 16 Sep 2012 00:00:00 UTC +00:00..Sat, 22 Sep 2012 23:59:59 UTC +00:00 now.all_month # => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00 now.all_quarter # => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00 now.all_year # => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
prev_day
, next_day
prev_day
및 next_day
메서드는 각각 이전 날짜와 다음 날짜의 시간을 반환합니다:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900 t.prev_day # => 2010-05-07 00:00:00 +0900 t.next_day # => 2010-05-09 00:00:00 +0900
주석: active_support/core_ext/time/calculations.rb
에 정의되어 있습니다.
prev_month
, next_month
prev_month
및 next_month
메서드는 동일한 날짜를 가진 이전 또는 다음 달의 시간을 반환합니다:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900 t.prev_month # => 2010-04-08 00:00:00 +0900 t.next_month # => 2010-06-08 00:00:00 +0900
그러한 날짜가 존재하지 않는 경우 해당 월의 마지막 날짜가 반환됩니다:
Time.new(2000, 5, 31).prev_month # => 2000-04-30 00:00:00 +0900 Time.new(2000, 3, 31).prev_month # => 2000-02-29 00:00:00 +0900 Time.new(2000, 5, 31).next_month # => 2000-06-30 00:00:00 +0900 Time.new(2000, 1, 31).next_month # => 2000-02-29 00:00:00 +0900
주석: active_support/core_ext/time/calculations.rb
에 정의되어 있습니다.
prev_year
, next_year
prev_year
및 next_year
메서드는 동일한 날짜/월을 가진 이전 또는 다음 연도의 시간을 반환합니다:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900 t.prev_year # => 2009-05-08 00:00:00 +0900 t.next_year # => 2011-05-08 00:00:00 +0900
2월 29일이 있는 윤년의 경우 28일이 반환됩니다:
t = Time.new(2000, 2, 29) # => 2000-02-29 00:00:00 +0900 t.prev_year # => 1999-02-28 00:00:00 +0900 t.next_year # => 2001-02-28 00:00:00 +0900
주석: active_support/core_ext/time/calculations.rb
에 정의되어 있습니다.
prev_quarter
, next_quarter
prev_quarter
및 next_quarter
메서드는 동일한 날짜를 가진 이전 또는 다음 분기의 시간을 반환합니다:
t = Time.local(2010, 5, 8) # => 2010-05-08 00:00:00 +0300 t.prev_quarter # => 2010-02-08 00:00:00 +0200 t.next_quarter # => 2010-08-08 00:00:00 +0300
그러한 날짜가 존재하지 않는 경우 해당 월의 마지막 날짜가 반환됩니다:
Time.local(2000, 7, 31).prev_quarter # => 2000-04-30 00:00:00 +0300 Time.local(2000, 5, 31).prev_quarter # => 2000-02-29 00:00:00 +0200 Time.local(2000, 10, 31).prev_quarter # => 2000-07-31 00:00:00 +0300 Time.local(2000, 11, 31).next_quarter # => 2001-03-01 00:00:00 +0200
prev_quarter
는 last_quarter
의 별칭입니다.
주석: active_support/core_ext/date_and_time/calculations.rb
에 정의되어 있습니다.
Time 생성자
액티브 서포트는 사용자 시간대가 정의된 경우 Time.zone.now
를, 그렇지 않으면 Time.now
를 반환하는 Time.current
를 정의합니다:
Time.zone_default # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...> Time.current # => Fri, 06 Aug 2010 17:11:58 CEST +02:00
DateTime
과 마찬가지로 past?
및 future?
술어는 Time.current
를 기준으로 합니다.
플랫폼에서 지원하는 범위를 벗어나는 시간을 생성하려면 usec가 버려지고 DateTime
객체가 반환됩니다.
지속 기간
Duration
객체를 Time 객체에 추가하거나 빼는 것이 가능합니다:
now = Time.current # => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now + 1.year # => Tue, 09 Aug 2011 23:21:11 UTC +00:00 now - 1.week # => Mon, 02 Aug 2010 23:21:11 UTC +00:00
이는 since
또는 advance
호출로 변환됩니다. 예를 들어 여기서는 달력 개혁에 맞는 점프를 얻습니다:
Time.utc(1582, 10, 3) + 5.days # => Mon Oct 18 00:00:00 UTC 1582
파일 익스텐션
atomic_write
File.atomic_write
클래스 메서드를 사용하면 읽는 사람이 중간 내용을 볼 수 없도록 파일에 쓸 수 있습니네, 번역을 계속하겠습니다.
File.atomic_write
클래스 메서드를 사용하면 읽는 사람이 중간 내용을 볼 수 없도록 파일에 쓸 수 있습니다.
파일 이름이 인수로 전달되며, 메서드는 쓰기 위해 열린 파일 핸들을 블록에 전달합니다. 블록이 완료되면 atomic_write
가 파일 핸들을 닫고 작업을 완료합니다.
예를 들어 Action Pack은 이 메서드를 사용하여 all.css
와 같은 자산 캐시 파일을 작성합니다:
File.atomic_write(joined_asset_path) do |cache| cache.write(join_asset_file_contents(asset_paths)) end
이를 위해 atomic_write
는 임시 파일을 생성합니다. 블록 내부 코드가 실제로 작성하는 파일이 바로 이 임시 파일입니다. 완료되면 임시 파일이 원래 파일로 이름이 변경되는데, 이는 POSIX 시스템에서 원자적 작업입니다. 대상 파일이 이미 존재하는 경우 atomic_write
는 소유권과 권한을 유지하면서 덮어씁니다. 그러나 파일 소유권이나 권한을 변경할 수 없는 경우가 있으며, 이 오류는 캐치되고 무시됩니다. 파일이 필요한 프로세스에 액세스할 수 있도록 하는 것은 사용자/파일 시스템의 책임입니다.
주의. atomic_write
가 수행하는 chmod 작업으로 인해 대상 파일에 ACL이 설정된 경우 ACL이 다시 계산/수정될 수 있습니다.
경고. atomic_write
로는 추가할 수 없습니다.
보조 파일은 표준 임시 파일 디렉토리에 작성되지만, 두 번째 인수로 원하는 디렉토리를 전달할 수 있습니다.
주석: active_support/core_ext/file/atomic.rb
에 정의되어 있습니다.
NameError 익스텐션
액티브 서포트는 NameError
에 missing_name?
을 추가합니다. 이 메서드는 예외가 인수로 전달된 이름 때문에 발생했는지 테스트합니다.
이름은 기호 또는 문자열로 제공될 수 있습니다. 기호는 bare 상수 이름에 대해, 문자열은 정규화된 상수 이름에 대해 테스트됩니다.
팁: 기호는 :"ActiveRecord::Base"
와 같이 정규화된 상수 이름을 나타낼 수 있으므로, 기호에 대한 동작은 편의를 위해 정의된 것이지 기술적으로 그래야 하는 것은 아닙니다.
예를 들어 ArticlesController
의 작업이 호출될 때 Rails는 ArticlesHelper
를 최적으로 사용하려고 시도합니다. 헬퍼 모듈이 존재하지 않는 것은 괜찮지만, articles_helper.rb
가 실제 알 수 없는 상수 때문에 예외를 발생시키는 경우에는 다시 발생시켜야 합니다. missing_name?
메서드는 이 두 경우를 구분하는 방법을 제공합니다:
def default_helper_module! module_name = name.delete_suffix("Controller") module_path = module_name.underscore helper module_path rescue LoadError => e raise e unless e.is_missing? "helpers/#{module_path}_helper" rescue NameError => e raise e unless e.missing_name? "#{module_name}Helper" end
주석: active_support/core_ext/name_error.rb
에 정의되어 있습니다.
LoadError 익스텐션
액티브 서포트는 LoadError
에 is_missing?
을 추가합니다.
경로 이름을 받아 is_missing?
는 예외가 해당 파일 때문에 발생했는지(확장자 ”.rb"는 제외) 테스트합니다.
예를 들어 ArticlesController
의 작업이 호출될 때 Rails는 articles_helper.rb
를 로드하려고 시도하지만, 해당 파일이 존재하지 않을 수 있습니다. 이는 문제가 되지 않으며, 헬퍼 모듈은 필수가 아니므로 Rails는 이 로드 오류를 무시합니다. 그러나 헬퍼 모듈이 존재하고 다른 라이브러리를 요구하는 동안 해당 라이브러리가 누락된 경우에는 예외를 다시 발생시켜야 합니다. is_missing?
메서드는 이 두 경우를 구분하는 방법을 제공합니다:
def default_helper_module! module_name = name.delete_suffix("Controller") module_path = module_name.underscore helper module_path rescue LoadError => e raise e unless e.is_missing? "helpers/#{module_path}_helper" rescue NameError => e raise e unless e.missing_name? "#{module_name}Helper" end
주석: active_support/core_ext/load_error.rb
에 정의되어 있습니다.
Pathname 익스텐션
existence
existence
메서드는 지정된 파일이 존재하면 수신기를 반환하고, 그렇지 않으면 nil
을 반환합니다. 다음과 같은 관용구에 유용합니다:
content = Pathname.new("file").existence&.read
주석: active_support/core_ext/pathname/existence.rb
에 정의되어 있습니다.
한국어 번역이 완료되었습니다.