Object

Object

Object은 모든 Ruby 객체의 기본 루트(root)예요. ObjectBasicObject에서 상속받는데, BasicObject 덕분에 별도의 객체 계층을 만들 수 있어요. Object의 메서드는 명시적으로 재정의하지 않는 한 모든 클래스에서 사용할 수 있어요. ObjectKernel 모듈을 믹스인해서, 내장 커널 함수들이 전역에서 접근 가능하게 해요. Object의 인스턴스 메서드는 Kernel 모듈이 정의하지만, 명확성을 위해 여기 문서에 함께 두기로 했어요.

Object를 상속받는 클래스에서 상수를 참조할 때는 전체 네임스페이스를 쓸 필요가 없어요. 예를 들어 YourClass 안에서 File을 참조하면 최상위 File 클래스를 찾아요.

출처: Ruby 4.0 API

본문

클래스 계층을 정리하면, ObjectBasicObject에서 상속받고 Kernel 모듈을 include해요. Object가 제공하는 메서드는 크게 조회(!~, <=>, ===, eql?, kind_of?, instance_of?, instance_variable_defined?, method, methods 등), 인스턴스 변수 조작(instance_variable_get, instance_variable_set, instance_variables, remove_instance_variable), 기타(dup, clone, freeze, hash, inspect, send, singleton_class 등)로 나눌 수 있어요. 아래 설명에서 인자 symbol은 심볼을 가리켜요. 따옴표로 감싼 문자열이거나 Symbol(예: :name)이에요.

Public Instance Methods

obj !~ other → true or false

두 객체가 일치하지 않으면(=~ 메서드를 사용해) true, 아니면 false를 돌려줘요.

self <=> other → 0 or nil

selfother를 비교해요. 같은 객체이거나 self == other가 참이면 0을, 아니면 nil을 돌려줘요.

o = Object.new
o <=> o     # => 0
o <=> o.dup # => nil

Comparable 모듈을 include하는 클래스는 인스턴스 메서드를 하나 정의해 이 메서드를 재정의해야 해요. 그 메서드는 other를 하나 받아 selfother보다 작으면 -1, 같으면 0, 크면 1, 비교할 수 없으면 nil을 돌려줘요.

true === other → true or false
false === other → true or false
nil === other → true or false

true 또는 false를 돌려줘요. objectObject의 인스턴스(그 많은 서브클래스가 아닌)라면 Object#==처럼 동작해요. 이 메서드는 보통 그 서브클래스들에서 case 문의 의미를 제공하도록 재정의돼요.

define_singleton_method(symbol, method) → symbol
define_singleton_method(symbol) { block } → symbol

리시버에 public 싱글턴 메서드를 정의해요. method 파라미터는 Proc, Method, UnboundMethod 객체일 수 있어요. 블록이 지정되면 그 블록이 메서드 본문으로 쓰여요. 블록이나 메서드에 파라미터가 있으면 그게 메서드 파라미터가 돼요.

class A
  class << self
    def class_name
      to_s
    end
  end
end
A.define_singleton_method(:who_am_i) do
  "I am: #{class_name}"
end
A.who_am_i   # ==> "I am: A"

guy = "Bob"
guy.define_singleton_method(:hello) { "#{self}: Hello there!" }
guy.hello    #=>  "Bob: Hello there!"

chris = "Chris"
chris.define_singleton_method(:greet) {|greeting| "#{greeting}, I'm Chris!" }
chris.greet("Hi") #=> "Hi, I'm Chris!"
display(port = $>) → nil

self를 주어진 포트에 써요.

1.display
"cat".display
[ 4, 5, 6 ].display
puts
# Output: 1cat[4, 5, 6]
dup → an_object

obj의 얕은 복사본을 만들어요—인스턴스 변수는 복사되지만 그 변수들이 참조하는 객체는 복사되지 않아요. 이 메서드는 클래스 고유의 동작이 있을 수 있는데, 있을 경우 그 클래스의 initialize_copy 메서드 문서에 설명돼요.

clonedup은 서브클래스에서 다른 의미를 가질 수 있어요. clone은 내부 상태를 포함해 객체를 복제하는 데 쓰이는 반면, dup은 보통 서브클래스 객체의 클래스를 사용해 새 인스턴스를 만드는 데 쓰여요. dup을 쓰면 객체가 extend한 모듈은 복사되지 않아요.

class Klass
  attr_accessor :str
end

module Foo
  def foo; 'foo'; end
end

s1 = Klass.new #=> #<Klass:0x401b3a38>
s1.extend(Foo) #=> #<Klass:0x401b3a38>
s1.foo #=> "foo"

s2 = s1.clone #=> #<Klass:0x401be280>
s2.foo #=> "foo"

s3 = s1.dup #=> #<Klass:0x401c1084>
s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401c1084>
enum_for(method = :each, *args) → enum
enum_for(method = :each, *args){|*args| block} → enum

obj에 대해 method를 호출해 열거할 새 Enumerator를 만들어요. 블록을 주면, 반복하지 않고도 열거자의 크기를 계산하는 데 쓰여요(Enumerator#size 참고). to_enum의 별칭이에요.

obj == other → true or false
equal?(other) → true or false
eql?(other) → true or false

동등성(Equality) — Object 수준에서 ==objother가 같은 객체일 때만 true를 돌려줘요. 보통 서브클래스에서 클래스 고유의 의미를 주도록 재정의해요. ==와 달리 equal?은 객체 정체성을 판별하므로 서브클래스에서 재정의하면 안 돼요. eql?은 두 객체가 같은 해시 키를 가리킬 때 true를 돌려줘요. Hash가 멤버 동등성을 검사할 때 써요. eql?true인 객체 쌍은 둘의 hash 값도 같아야 하므로, eql?를 재정의하면 hash도 함께 재정의해야 해요. Object 클래스 객체에서 eql?==과 동의어예요. Numeric 같은 예외가 있는데, ==에서는 타입 변환을 하지만 eql?에서는 하지 않아요.

1 == 1.0    #=> true
1.eql? 1.0  #=> false
extend(module, ...) → obj

각 파라미터로 주어진 모듈의 인스턴스 메서드를 obj에 추가해요. 이 모듈의 메서드들은 obj의 싱글턴 메서드가 돼요.

module Mod
  def hello
    "Hello from Mod.\n"
  end
end

class Klass
  def hello
    "Hello from Klass.\n"
  end
end

k = Klass.new
k.hello         #=> "Hello from Klass.\n"
k.extend(Mod)   #=> #<Klass:0x401b3bc8>
k.hello         #=> "Hello from Mod.\n"
freeze → obj

obj에 대한 추가 수정을 막아요. 수정을 시도하면 FrozenError가 나요. frozen 객체를 풀 방법은 없어요. Object#frozen?도 참고하세요. self를 돌려줘요. Integer, Float, Symbol 클래스의 객체는 항상 frozen이에요.

a = [ "a", "b", "c" ]
a.freeze
a << "z"
# prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
hash → integer

self의 정수 해시 값을 돌려줘요. foo.eql?(bar)이면 foo.hash == bar.hash라는 성질이 있어요. Hash 클래스는 두 객체가 같은 해시 키인지 정할 때 hasheql? 둘 다 사용해요. 사용자 정의 클래스의 hash를 구현할 때는 클래스 이름과 인스턴스에서 중요한 값들로 Array#hash를 쓰는 게 좋은 습관이에요.

def hash
  [self.class, a, b, c].hash
end

해시 값은 Ruby의 호출/구현마다 달라질 수 있어요. Ruby 호출·구현에 걸쳐 안정된 해시류 식별자가 필요하면 커스텀 메서드로 생성해야 해요.

inspect → string

obj의 사람이 읽기 좋은 표현을 담은 문자열을 돌려줘요. 기본 inspect는 객체의 클래스 이름, 메모리 주소 인코딩, 인스턴스 변수와 값 목록을 보여줘요. 사용자 정의 클래스는 이 메서드를 재정의해 더 나은 표현을 제공하는 게 좋아요. objinstance_variables_to_inspect에 응답하면, 그 반환 배열에 나열된 인스턴스 변수만 inspect 문자열에 포함돼요.

[ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]"
Time.new.inspect               #=> "2008-03-08 19:43:39 +0900"

class Bar
  def initialize
    @bar = 1
  end
end
Bar.new.inspect  #=> "#<Bar:0x0300c868 @bar=1>"
instance_of?(class) → true or false

obj가 주어진 클래스의 인스턴스이면 true를 돌려줘요. Object#kind_of?도 참고하세요. 서브클래스의 인스턴스는 false예요.

class A;     end
class B < A; end
class C < B; end

b = B.new
b.instance_of? A   #=> false
b.instance_of? B   #=> true
b.instance_of? C   #=> false
instance_variable_defined?(symbol) → true or false
instance_variable_defined?(string) → true or false

obj에 주어진 인스턴스 변수가 정의돼 있으면 true를 돌려줘요. String 인자는 심볼로 변환돼요.

instance_variable_get(symbol) → obj
instance_variable_get(string) → obj

주어진 인스턴스 변수의 값을 돌려줘요. 설정되지 않았으면 nil. 일반 인스턴스 변수는 이름에 @ 부분을 포함해야 해요. 심볼이 유효한 인스턴스 변수 이름이 아니면 NameError. String 인자는 심볼로 변환돼요.

instance_variable_set(symbol, obj) → obj
instance_variable_set(string, obj) → obj

symbol 이름의 인스턴스 변수를 주어진 객체로 설정해요. 클래스 작성자가 의도한 캡슐화를 우회할 수 있으니 주의해서 써야 해요. 변수가 이 호출 전에 존재할 필요는 없어요.

instance_variables → array

리시버의 인스턴스 변수 이름 배열을 돌려줘요. 접근자를 정의했다고 해서 대응 인스턴스 변수가 만들어지는 건 아니에요.

is_a?(class) → true or false

classobj의 클래스이거나, obj의 슈퍼클래스/obj에 include된 모듈 중 하나면 true를 돌려줘요. kind_of?의 별칭이에요.

itself → obj

리시버를 돌려줘요.

string = "my string"
string.itself.object_id == string.object_id  #=> true
kind_of?(class) → true or false

classobj의 클래스이거나, obj의 슈퍼클래스/obj에 include된 모듈 중 하나면 true를 돌려줘요. is_a?로도 부를 수 있어요.

method(sym) → method

obj에서 이름 붙은 메서드를 리시버로 찾아 Method 객체를 돌려줘요(없으면 NameError). Method 객체는 obj의 객체 인스턴스 안에서 클로저처럼 동작해서, 인스턴스 변수와 self 값이 계속 사용 가능해요. Methodto_proc을 구현하므로 반복자와 함께 쓸 수 있어요.

[ 1, 2, 3 ].each(&method(:puts))  # => prints 3 lines to stdout
methods(regular=true) → array

obj의 public·protected 메서드 이름 목록을 돌려줘요. obj의 조상에서 접근 가능한 모든 메서드를 포함해요. 선택 파라미터가 falseobj의 public·protected 싱글턴 메서드 배열만 돌려주고, obj에 include된 모듈의 메서드는 포함하지 않아요.

nil? → true or false

nil 객체만 nil?true로 응답해요.

Object.new.nil?  #=> false
nil.nil?         #=> true
__id__ → integer
object_id → integer

obj의 정수 식별자를 돌려줘요. 주어진 객체에 대한 모든 object_id 호출은 같은 번호를 돌려주고, 활성 객체 두 개가 id를 공유하지 않아요. immediate 값과 frozen 문자열 리터럴 같은 일부 내장 클래스 객체는 최적화를 위해 재사용돼요. BasicObject__id__를, Kernelobject_id를 구현해요. immediate 값(nil, true, false, Fixnum, Symbol, 일부 Float)은 참조가 아니라 값으로 전달돼요.

Object.new.object_id  == Object.new.object_id  # => false
(21 * 2).object_id    == (21 * 2).object_id    # => true
"hello".object_id     == "hello".object_id     # => false
"hi".freeze.object_id == "hi".freeze.object_id # => true
private_methods(all=true) → array

obj가 접근 가능한 private 메서드 목록을 돌려줘요. allfalse면 리시버 자신의 메서드만 나열해요.

protected_methods(all=true) → array

obj가 접근 가능한 protected 메서드 목록을 돌려줘요. allfalse면 리시버 자신의 메서드만 나열해요.

public_method(sym) → method

method와 비슷하지만 public 메서드만 검색해요.

public_methods(all=true) → array

obj가 접근 가능한 public 메서드 목록을 돌려줘요. allfalse면 리시버 자신의 메서드만 나열해요.

public_send(symbol [, args...]) → obj
public_send(string [, args...]) → obj

symbol로 식별되는 메서드를 지정된 인자로 호출해요. send와 달리 public_send는 public 메서드만 호출해요. 문자열로 식별되면 심볼로 변환돼요.

1.public_send(:puts, "hello")  # causes NoMethodError
remove_instance_variable(symbol) → obj
remove_instance_variable(string) → obj

obj에서 이름 붙은 인스턴스 변수를 제거하고 그 값을 돌려줘요. 이름은 심볼 또는 문자열로 넘길 수 있어요.

respond_to?(symbol, include_all=false) → true or false
respond_to?(string, include_all=false) → true or false

obj가 주어진 메서드에 응답하면 true를 돌려줘요. private·protected 메서드는 선택 두 번째 파라미터가 true일 때만 검색에 포함돼요. 메서드가 구현되지 않았으면(예: Windows의 Process.fork, GNU/Linux의 File.lchmod) false를 돌려줘요. 메서드가 정의되지 않았으면 respond_to_missing?을 호출해 그 결과를 돌려줘요.

respond_to_missing?(symbol, include_all) → true or false
respond_to_missing?(string, include_all) → true or false

직접 쓰지 마세요. objid 메서드에 응답할 수 있는지 돌려주는 훅 메서드예요. respond_to?BasicObject 예시를 참고하세요.

send(symbol [, args...]) → obj
__send__(symbol [, args...]) → obj
send(string [, args...]) → obj
__send__(string [, args...]) → obj

symbol로 식별되는 메서드를 지정된 인자로 호출해요. BasicObject__send__를, Kernelsend를 구현해요. objSocket처럼 같은 이름의 메서드를 가질 때 __send__send보다 안전해요. public_send도 참고하세요.

class Klass
  def hello(*args)
    "Hello " + args.join(' ')
  end
end
k = Klass.new
k.send :hello, "gentle", "readers"  #=> "Hello gentle readers"
singleton_class → class

obj의 싱글턴 클래스를 돌려줘요. obj에 싱글턴 클래스가 없으면 새로 만들어요. objnil, true, false면 각각 NilClass, TrueClass, FalseClass를 돌려줘요. Integer, Float, Symbol이면 TypeError를 던져요.

singleton_method(sym) → method

method와 비슷하지만 싱글턴 메서드만 검색해요.

singleton_methods(all=true) → array

obj의 싱글턴 메서드 이름 배열을 돌려줘요. alltrueobj에 include된 모듈의 메서드도 포함돼요. public·protected 싱글턴 메서드만 돌려줘요.

to_enum(method = :each, *args) → enum
to_enum(method = :each, *args) {|*args| block} → enum

obj에 대해 method를 호출해 열거할 새 Enumerator를 만들어요. 블록을 주면 열거자의 크기를 반복 없이 계산하는 데 쓰여요. enum_for로도 부를 수 있어요.

to_s → string

obj를 나타내는 문자열을 돌려줘요. 기본 to_s는 객체의 클래스와 객체 id 인코딩을 출력해요. 특별한 케이스로, Ruby 프로그램의 초기 실행 문맥인 최상위 객체는 "main"을 돌려줘요.