Struct
Struct
Struct 클래스는 값을 저장하고 꺼낼 수 있는 간단한 클래스를 쉽게 만들 수 있게 해 줘요.
출처: Ruby 3.3 API
본문
다음 예제는 Struct의 하위 클래스인 Struct::Customer를 만들어요. 첫 번째 인자인 문자열은 하위 클래스의 이름이고, 나머지 심볼 인자들이 새 하위 클래스의 멤버들을 결정해요.
Customer = Struct.new('Customer', :name, :address, :zip)
Customer.name # => "Struct::Customer"
Customer.class # => Class
Customer.superclass # => Struct
각 멤버에 대응해 값을 저장·조회하는 writer·reader 메서드 두 개가 생겨요.
methods = Customer.instance_methods false
methods # => [:zip, :address=, :zip=, :address, :name, :name=]
하위 클래스의 인스턴스는 ::new로 만들고 멤버에 값을 할당할 수 있어요.
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe # => #<struct Struct::Customer name="Joe Smith", address="123 Maple, Anytown NC", zip=12345>
멤버 값은 이렇게 관리할 수 있어요. 멤버 이름은 문자열이나 심볼로 표현할 수 있어요.
joe.name # => "Joe Smith"
joe.name = 'Joseph Smith'
joe.name # => "Joseph Smith"
joe[:name] # => "Joseph Smith"
joe[:name] = 'Joseph Smith, Jr.'
joe['name'] # => "Joseph Smith, Jr."
여기에 있는 것 (What's Here)
Struct는 Object에서 상속받고 Enumerable을 포함해요. 불변 값 객체를 더 엄격하게 정의하는 유사 개념으로 Data도 참고할 수 있어요.
- 서브클래스 생성:
::new—Struct의 새 하위 클래스를 돌려줘요. - 조회:
hash— 정수 해시 코드를 돌려줘요.length,size— 멤버 수를 돌려줘요. - 비교:
==— 멤버 값을==로 비교해 주어진 객체와 같은지 돌려줘요.eql?— 멤버 값을eql?로 비교해요. - 가져오기:
[]— 주어진 멤버 이름의 값을 돌려줘요.to_a,values,deconstruct— 멤버 값을 배열로 돌려줘요.deconstruct_keys— 주어진 멤버 이름들의 이름/값 쌍 해시를 돌려줘요.dig— 중첩 객체에서 주어진 경로의 객체를 돌려줘요.members— 멤버 이름 배열을 돌려줘요.select,filter— 주어진 블록으로 선택된 멤버 값 배열을 돌려줘요.values_at— 주어진 멤버 이름들에 대한 값 배열을 돌려줘요. - 할당:
[]=— 주어진 멤버 이름에 값을 할당해요. - 반복:
each— 각 멤버 이름으로 블록을 호출해요.each_pair— 각 멤버 이름/값 쌍으로 블록을 호출해요. - 변환:
inspect,to_s—self의 문자열 표현을 돌려줘요.to_h— 멤버 이름/값 쌍의 해시를 돌려줘요.
Public Class Methods
StructClass::keyword_init? → true or falsy value
클래스가 keyword_init: true로 초기화됐으면 true, 아니면 nil이나 false를 돌려줘요.
Foo = Struct.new(:a)
Foo.keyword_init? # => nil
Bar = Struct.new(:a, keyword_init: true)
Bar.keyword_init? # => true
Baz = Struct.new(:a, keyword_init: false)
Baz.keyword_init? # => false
StructClass::members → array_of_symbols
Struct 하위 클래스의 멤버 이름을 배열로 돌려줘요.
Customer = Struct.new(:name, :address, :zip)
Customer.members # => [:name, :address, :zip]
new(*member_names, keyword_init: nil){|Struct_subclass| ... } → Struct_subclass
new(class_name, *member_names, keyword_init: nil){|Struct_subclass| ... } → Struct_subclass
new(*member_names) → Struct_subclass_instance
new(**member_names) → Struct_subclass_instance
Struct.new는 Struct의 새 하위 클래스를 돌려줘요. 새 하위 클래스는:
- 익명일 수도 있고
class_name으로 이름이 붙을 수도 있어요. member_names로 주어진 멤버들을 가질 수 있어요.- 일반 인자나 키워드 인자로 초기화될 수 있어요.
새 하위 클래스는 자신의 ::new 메서드를 가져요.
Foo = Struct.new('Foo', :foo, :bar) # => Struct::Foo
f = Foo.new(0, 1) # => #<struct Struct::Foo foo=0, bar=1>
클래스 이름: 문자열 인자 class_name을 주면 Struct::class_name이라는 이름의 새 하위 클래스를 돌려줘요. 문자열 없이 부르면 익명 하위 클래스를 돌려줘요.
블록이 주어지면 만들어진 하위 클래스가 블록에 넘겨져요.
Customer = Struct.new('Customer', :name, :address) do |new_class|
p "The new subclass is #{new_class}"
def greeting
"Hello #{name} at #{address}"
end
end # => Struct::Customer
dave = Customer.new('Dave', '123 Main')
dave # => #<struct Struct::Customer name="Dave", address="123 Main">
dave.greeting # => "Hello Dave at 123 Main"
키워드 인자 keyword_init:는 받아들이는 인자 타입을 한 가지로 강제할 수 있어요.
KeywordsOnly = Struct.new(:foo, :bar, keyword_init: true)
KeywordsOnly.new(bar: 1, foo: 0) # => #<struct KeywordsOnly foo=0, bar=1>
KeywordsOnly.new(0, 1) # Raises ArgumentError: wrong number of arguments
PositionalOnly = Struct.new(:foo, :bar, keyword_init: false)
PositionalOnly.new(0, 1) # => #<struct PositionalOnly foo=0, bar=1>
Any = Struct.new(:foo, :bar, keyword_init: nil)
Any.new(foo: 1, bar: 2) # => #<struct Any foo=1, bar=2>
Any.new(1, 2) # => #<struct Any foo=1, bar=2>
Public Instance Methods
self == other → true or false
다음 두 조건이 모두 참일 때만 true를, 아니면 false를 돌려줘요.
other.class == self.class- 각 멤버 이름
name에 대해other.name == self.name
struct[name] → object
struct[n] → object
심볼 또는 문자열 인자 name이 주어지면 그 이름의 멤버 값을 돌려줘요. 멤버 이름이 아니면 NameError가 나요. 정수 인자 n이 주어지면 범위 안이면 self.values[n]을 돌려주고, 범위를 벗어나면 IndexError가 나요.
struct[name] = value → value
struct[n] = value → value
멤버에 값을 할당해요. 이름이 멤버가 아니면 NameError, 정수 n이 범위 밖이면 IndexError가 나요.
as_json(*)
Struct#as_json과 Struct.json_create는 Struct 객체를 직렬화·역직렬화해요. deconstruct는 to_a의 별칭이에요.
deconstruct_keys(array_of_names) → hash
주어진 멤버 이름들에 대한 이름/값 쌍 해시를 돌려줘요. array_of_names가 nil이면 모든 이름·값을 돌려줘요.
dig(name, *identifiers) → object
dig(n, *identifiers) → object
중첩 객체들 사이에서 주어진 경로의 객체를 찾아 돌려줘요. Dig Methods를 참고하세요.
each {|value| ... } → self
each → enumerator
각 멤버의 값으로 블록을 호출하고 self를 돌려줘요. 블록이 없으면 Enumerator를 돌려줘요.
each_pair {|(name, value)| ... } → self
each_pair → enumerator
각 멤버 이름/값 쌍으로 블록을 호출하고 self를 돌려줘요.
eql?(other) → true or false
==와 같지만 멤버 값을 eql?로 비교해요.
hash → integer
self의 정수 해시 값을 돌려줘요. 같은 클래스·같은 내용의 두 struct는 같은 해시 코드를 가져요.
inspect → string
self의 문자열 표현을 돌려줘요. to_s도 별칭이에요.
members → array_of_symbols
self의 멤버 이름을 배열로 돌려줘요.
select {|value| ... } → array
select → enumerator
블록이 참 값을 돌려주는 멤버 값들의 배열을 돌려줘요. 블록이 없으면 Enumerator를 돌려줘요. filter도 별칭이에요.
size → integer
멤버 수를 돌려줘요. length도 별칭이에요.
to_a → array
self의 값을 배열로 돌려줘요. values, deconstruct도 별칭이에요.
to_h → hash
to_h {|name, value| ... } → hash
각 멤버의 이름과 값을 담은 해시를 돌려줘요. 블록이 주어지면 각 이름/값 쌍으로 호출하고, 블록이 반환한 2-요소 배열이 반환 해시의 키/값 쌍이 돼요. 블록이 부적절한 값을 반환하면 ArgumentError가 나요.
to_json(*args)
self를 나타내는 JSON 문자열을 돌려줘요.
values_at(*integers) → array
values_at(integer_range) → array
self의 값 배열을 돌려줘요. 정수 인자들로는 각 값이, 정수 범위 인자로는 범위 요소로 선택된 값들이 담겨요. 범위 요소가 구조보다 크면 nil로 채워져요.