Spec-Zone.ru › Ruby 4.0

класс Object

Родительский класс:
BasicObject
Подключённые модули:
Kernel

Object — корневой класс по умолчанию для всех объектов Ruby. Object наследуется от BasicObject, что позволяет создавать альтернативные иерархии объектов. Методы Object доступны всем классам, если только они явно не переопределены.

Object подключает модуль Kernel, делая встроенные функции ядра глобально доступными. Хотя методы экземпляра Object определены модулем Kernel, для ясности мы решили задокументировать их здесь.

При обращении к константам в классах, наследующих от Object, не нужно указывать полное пространство имён. Например, обращение к File внутри YourClass приведёт к поиску класса File верхнего уровня.

В описаниях методов Object параметр symbol обозначает символ — заключённую в кавычки строку или Symbol (например, :name).

Что здесь есть

Сначала — о том, что находится в других местах. Класс Object:

  • Наследуется от класса BasicObject.

  • Подключает модуль Kernel.

Здесь класс Object предоставляет методы для:

  • Проверки

  • Переменных экземпляра

  • Других операций

Проверка

  • !~: возвращает true, если self не соответствует заданному объекту, в противном случае — false.

  • <=>: возвращает 0, если self и заданный объект object являются одним и тем же объектом или если self == object; в противном случае возвращает nil.

  • ===: реализует равенство для case, фактически выполняя то же, что и вызов ==.

  • eql?: реализует равенство хешей, фактически выполняя то же, что и вызов ==.

  • kind_of? (с псевдонимом is_a?): возвращает, является ли заданный аргумент предком singleton-класса self.

  • instance_of?: возвращает, является ли self экземпляром заданного класса.

  • instance_variable_defined?: возвращает, определена ли заданная переменная экземпляра в self.

  • method: возвращает объект Method для заданного метода в self.

  • methods: возвращает массив имён-символов открытых и защищённых методов в self.

  • nil?: возвращает false. (Только nil отвечает true на вызов метода nil?.)

  • object_id: возвращает целое число, соответствующее self и уникальное в текущем процессе.

  • private_methods: возвращает массив имён-символов закрытых методов в self.

  • protected_methods: возвращает массив имён-символов защищённых методов в self.

  • public_method: возвращает объект Method для заданного открытого метода в self.

  • public_methods: возвращает массив имён-символов открытых методов в self.

  • respond_to?: возвращает, отвечает ли self на вызов заданного метода.

  • singleton_class: возвращает singleton-класс self.

  • singleton_method: возвращает объект Method для заданного singleton-метода в self.

  • singleton_methods: возвращает массив имён-символов singleton-методов в self.

  • define_singleton_method: определяет singleton-метод в self с заданным именем метода-символом и блоком или proc.

  • extend: подключает заданные модули к singleton-классу self.

  • public_send: вызывает заданный открытый метод в self с заданным аргументом.

  • send: вызывает заданный метод в self с заданным аргументом.

Переменные экземпляра

  • instance_variable_get: возвращает значение заданной переменной экземпляра в self или nil, если переменная экземпляра не задана.

  • instance_variable_set: задаёт значение заданной переменной экземпляра в self равным указанному объекту.

  • instance_variables: возвращает массив имён-символов переменных экземпляра в self.

  • remove_instance_variable: удаляет именованную переменную экземпляра из self.

Другие операции

  • clone: возвращает поверхностную копию self, включая singleton-класс и состояние заморозки.

  • define_singleton_method: определяет singleton-метод в self с заданным именем метода-символом и блоком или proc.

  • display: выводит self в заданный поток IO или в $stdout.

  • dup: возвращает поверхностную незамороженную копию self.

  • enum_for (с псевдонимом to_enum): возвращает Enumerator для self, используя заданный метод, аргументы и блок.

  • extend: подключает заданные модули к singleton-классу self.

  • freeze: запрещает дальнейшие изменения self.

  • hash: возвращает целочисленное хеш-значение для self.

  • inspect: возвращает удобное для чтения строковое представление self.

  • itself: возвращает self.

  • method_missing: метод, вызываемый при вызове неопределённого метода для self.

  • public_send: вызывает заданный открытый метод в self с заданным аргументом.

  • send: вызывает заданный метод в self с заданным аргументом.

  • to_s: возвращает строковое представление self.

Константы

ARGF

ARGF — это поток, предназначенный для использования в скриптах, обрабатывающих файлы, указанные в аргументах командной строки или переданные через STDIN.

Подробнее см. ARGF (класс).

ARGV

ARGV содержит аргументы командной строки, используемые для запуска ruby.

Для обработки аргументов командной строки можно использовать библиотеку, например OptionParser.

CROSS_COMPILING

Не nil, если настроена кросс-компиляция.

DATA

DATA — это File, содержащий раздел данных исполняемого файла. Чтобы создать раздел данных, используйте __END__:

$ cat t.rb
puts DATA.gets
__END__
hello world!

$ ruby t.rb
hello world!
ENV

ENV — это похожий на Hash интерфейс доступа к переменным окружения.

Подробнее см. ENV (класс).

Ripper

Это записывает преобразование prism ripper в константу Ripper, чтобы пользователи могли прозрачно использовать Ripper без каких-либо изменений.

STDERR

Содержит исходный поток stderr

STDIN

Содержит исходный поток stdin

STDOUT

Содержит исходный поток stdout

TOPLEVEL_BINDING

Binding области верхнего уровня

Открытые методы класса

yaml_tag (url) Показать исходный код
# File ext/psych/lib/psych/core_ext.rb, line 3
def self.yaml_tag url
  Psych.add_tag(url, self)
end

Публичные методы экземпляра

obj !~ other → true or false Показать исходный код
static VALUE
rb_obj_not_match(VALUE obj1, VALUE obj2)
{
    VALUE result = rb_funcall(obj1, id_match, 1, obj2);
    return rb_obj_not(result);
}

Возвращает true, если два объекта не совпадают (с использованием метода =~), иначе false.

self <=> other → 0 or nil Показать исходный код
static VALUE
rb_obj_cmp(VALUE obj1, VALUE obj2)
{
    if (rb_equal(obj1, obj2))
        return INT2FIX(0);
    return Qnil;
}

Сравнивает self и other.

Возвращает:

  • 0, если self и other — один и тот же объект или если self == other.

  • nil в противном случае.

Примеры:

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

Класс, подключающий модуль Comparable, должен переопределить этот метод, определив метод экземпляра, который:

  • Принимает один аргумент, other.

  • Возвращает:

    • -1, если self меньше other.

    • 0, если self равно other.

    • 1, если self больше other.

    • nil, если эти два значения несопоставимы.

true === other → true or false Показать исходный код
false === other → true or false
nil === other → true or false
#define case_equal rb_equal

Возвращает true или false.

Подобно Object#==, если object является экземпляром Object (а не экземпляром одного из многочисленных подклассов этого класса).

Этот метод обычно переопределяется подклассами, чтобы обеспечить осмысленную семантику в инструкциях case.

DelegateClass (superclass, &block) Показать исходный код
# File lib/delegate.rb, line 395
def DelegateClass(superclass, &block)
  klass = Class.new(Delegator)
  ignores = [*::Delegator.public_api, :to_s, :inspect, :=~, :!~, :===]
  protected_instance_methods = superclass.protected_instance_methods
  protected_instance_methods -= ignores
  public_instance_methods = superclass.public_instance_methods
  public_instance_methods -= ignores

  normal, special = public_instance_methods.partition { |m| m.match?(/\A[a-zA-Z]\w*[!\?]?\z/) }

  source = normal.map do |method|
    "def #{method}(...); __getobj__.#{method}(...); end"
  end

  protected_instance_methods.each do |method|
    source << "def #{method}(...); __getobj__.__send__(#{method.inspect}, ...); end"
  end

  klass.module_eval do
    def __getobj__ # :nodoc:
      unless defined?(@delegate_dc_obj)
        return yield if block_given?
        __raise__ ::ArgumentError, "not delegated"
      end
      @delegate_dc_obj
    end

    def __setobj__(obj)  # :nodoc:
      __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
      @delegate_dc_obj = obj
    end

    class_eval(source.join(";"), __FILE__, __LINE__)

    special.each do |method|
      define_method(method, Delegator.delegating_block(method))
    end

    protected(*protected_instance_methods)
  end

  klass.define_singleton_method :public_instance_methods do |all=true|
    super(all) | superclass.public_instance_methods
  end
  klass.define_singleton_method :protected_instance_methods do |all=true|
    super(all) | superclass.protected_instance_methods
  end
  klass.define_singleton_method :instance_methods do |all=true|
    super(all) | superclass.instance_methods
  end
  klass.define_singleton_method :public_instance_method do |name|
    super(name)
  rescue NameError
    raise unless self.public_instance_methods.include?(name)
    superclass.public_instance_method(name)
  end
  klass.define_singleton_method :instance_method do |name|
    super(name)
  rescue NameError
    raise unless self.instance_methods.include?(name)
    superclass.instance_method(name)
  end
  klass.module_eval(&block) if block
  return klass
end

Основной интерфейс этой библиотеки. Используйте его для настройки делегирования при определении класса.

class MyClass < DelegateClass(ClassToDelegateTo) # Step 1
  def initialize
    super(obj_of_ClassToDelegateTo)              # Step 2
  end
end

или:

MyClass = DelegateClass(ClassToDelegateTo) do    # Step 1
  def initialize
    super(obj_of_ClassToDelegateTo)              # Step 2
  end
end

Вот пример использования из Tempfile, который на самом деле представляет собой объект File с несколькими особыми правилами о месте хранения и о том, когда следует удалять File. Это почти идеальный учебный пример использования делегирования.

class Tempfile < DelegateClass(File)
  # constant and class member data initialization...

  def initialize(basename, tmpdir=Dir::tmpdir)
    # build up file path/name in var tmpname...

    @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)

    # ...

    super(@tmpfile)

    # below this point, all methods of File are supported...
  end

  # ...
end
Вызов метода суперкласса
Digest(name) → digest_subclass Показать исходный код
# File ext/digest/lib/digest.rb, line 110
def Digest(name)
  const = name.to_sym
  Digest::REQUIRE_MUTEX.synchronize {
    # Ignore autoload's because it is void when we have #const_missing
    Digest.const_missing(const)
  }
rescue LoadError
  # Constants do not necessarily rely on digest/*.
  if Digest.const_defined?(const)
    Digest.const_get(const)
  else
    raise
  end
end

Возвращает подкласс Digest по name потокобезопасным способом, даже если используется загрузка по требованию.

require 'digest'

Digest("MD5")
# => Digest::MD5

Digest(:SHA256)
# => Digest::SHA256

Digest(:Foo)
# => LoadError: library not found for class Digest::Foo -- digest/foo
define_singleton_method(symbol, method) → symbol Показать исходный код
define_singleton_method(symbol) { block } → symbol
static VALUE
rb_obj_define_method(int argc, VALUE *argv, VALUE obj)
{
    VALUE klass = rb_singleton_class(obj);
    const rb_scope_visibility_t scope_visi = {METHOD_VISI_PUBLIC, FALSE};

    return rb_mod_define_method_with_visibility(argc, argv, klass, &scope_visi);
}

Определяет публичный метод singleton для получателя. Параметр 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 Показать исходный код
static VALUE
rb_obj_display(int argc, VALUE *argv, VALUE self)
{
    VALUE out;

    out = (!rb_check_arity(argc, 0, 1) ? rb_ractor_stdout() : argv[0]);
    rb_io_write(out, self);

    return Qnil;
}

Записывает self в указанный поток:

1.display
"cat".display
[ 4, 5, 6 ].display
puts

Вывод:

1cat[4, 5, 6]
dup → an_object Показать исходный код
VALUE
rb_obj_dup(VALUE obj)
{
    VALUE dup;

    if (special_object_p(obj)) {
        return obj;
    }
    dup = rb_obj_alloc(rb_obj_class(obj));
    return rb_obj_dup_setup(obj, dup);
}

Создает поверхностную копию obj — копируются переменные экземпляра obj, но не объекты, на которые они ссылаются.

Этот метод может иметь поведение, специфичное для класса. Если это так, оно описано в разделе #initialize_copy класса.

о dup и clone

В целом clone и dup могут иметь разную семантику в классах-потомках. В то время как clone используется для дублирования объекта вместе с его внутренним состоянием, dup обычно использует класс объекта-потомка для создания нового экземпляра.

При использовании dup не копируются модули, которыми был расширен объект.

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

Создает новый Enumerator, который будет выполнять перебор, вызывая method для obj и передавая args, если они есть. Значения, выданные методом, становятся значениями перечислителя.

Если задан блок, он будет использоваться для вычисления размера перечислителя без необходимости выполнять перебор (см. Enumerator#size).

Примеры

str = "xyz"

enum = str.enum_for(:each_byte)
enum.each { |b| puts b }
# => 120
# => 121
# => 122

# protect an array from being modified by some_method
a = [1, 2, 3]
some_method(a.to_enum)

# String#split in block form is more memory-effective:
very_large_string.split("|") { |chunk| return chunk if chunk.include?('DATE') }
# This could be rewritten more idiomatically with to_enum:
very_large_string.to_enum(:split, "|").lazy.grep(/DATE/).first

При определении методов для универсального Enumerable обычно вызывают to_enum на случай, если блок не передан.

Вот такой пример с передачей параметров и блоком для определения размера:

module Enumerable
  # a generic method to repeat the values of any enumerable
  def repeat(n)
    raise ArgumentError, "#{n} is negative!" if n < 0
    unless block_given?
      return to_enum(__method__, n) do # __method__ is :repeat here
        sz = size     # Call size and multiply by n...
        sz * n if sz  # but return nil if size itself is nil
      end
    end
    each do |*val|
      n.times { yield *val }
    end
  end
end

%i[hello world].repeat(2) { |w| puts w }
  # => Prints 'hello', 'hello', 'world', 'world'
enum = (1..14).repeat(3)
  # => returns an Enumerator when called without a block
enum.first(4) # => [1, 1, 1, 2]
enum.size # => 42
Псевдоним для: to_enum
obj == other → true or false Показать исходный код
equal?(other) → true or false
eql?(other) → true or false
VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    return RBOOL(obj1 == obj2);
}

Равенство — на уровне Object метод == возвращает true, только если obj и other — один и тот же объект. Обычно этот метод переопределяют в классах-потомках, чтобы задать значение, специфичное для класса.

В отличие от ==, метод equal? никогда не следует переопределять в подклассах, поскольку он используется для определения идентичности объектов (то есть a.equal?(b) тогда и только тогда, когда a — тот же объект, что и b):

obj = "a"
other = obj.dup

obj == other      #=> true
obj.equal? other  #=> false
obj.equal? obj    #=> true

Метод eql? возвращает true, если obj и other ссылаются на один и тот же ключ хеша. Метод используется классом Hash для проверки равенства элементов. Для любой пары объектов, для которых eql? возвращает true, значения hash обоих объектов должны быть равны. Поэтому любой подкласс, переопределяющий eql?, должен также соответствующим образом переопределить hash.

Для объектов класса Object метод eql? является синонимом ==. Подклассы обычно сохраняют эту традицию, назначая eql? псевдонимом переопределенного метода ==, но есть исключения. Например, типы Numeric выполняют преобразование типов при использовании ==, но не при использовании eql?, поэтому:

1 == 1.0     #=> true
1.eql? 1.0   #=> false
extend(module, ...) → obj Показать исходный код
static VALUE
rb_obj_extend(int argc, VALUE *argv, VALUE obj)
{
    int i;
    ID id_extend_object, id_extended;

    CONST_ID(id_extend_object, "extend_object");
    CONST_ID(id_extended, "extended");

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    for (i = 0; i < argc; i++) {
        Check_Type(argv[i], T_MODULE);
        if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
            rb_raise(rb_eTypeError, "Cannot extend object with refinement");
        }
    }
    while (argc--) {
        rb_funcall(argv[argc], id_extend_object, 1, obj);
        rb_funcall(argv[argc], id_extended, 1, obj);
    }
    return 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 Показать исходный код
VALUE
rb_obj_freeze(VALUE obj)
{
    if (!OBJ_FROZEN(obj)) {
        OBJ_FREEZE(obj);
        if (SPECIAL_CONST_P(obj)) {
            rb_bug("special consts should be frozen.");
        }
    }
    return obj;
}

Запрещает дальнейшее изменение obj. Если будет предпринята попытка изменить объект, возникнет исключение FrozenError. Разморозить замороженный объект невозможно. См. также Object#frozen?.

Этот метод возвращает self.

a = [ "a", "b", "c" ]
a.freeze
a << "z"

выводит:

prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
 from prog.rb:3

Объекты следующих классов всегда заморожены: Integer, Float, Symbol.

hash → integer Показать исходный код
VALUE
rb_obj_hash(VALUE obj)
{
    long hnum = any_hash(obj, objid_hash);
    return ST2FIX(hnum);
}

Возвращает целочисленное хеш-значение для self; выполняется условие: если foo.eql?(bar), то foo.hash == bar.hash.

Класс Hash использует методы hash и eql?, чтобы определить, следует ли считать два объекта, используемые в качестве ключей хеша, одним и тем же ключом. Хеш-значение, превышающее емкость Integer, усекается перед использованием.

Многие основные классы переопределяют метод Object#hash; другие основные классы (например, Integer) вычисляют хеш внутри себя и не вызывают метод hash при использовании в качестве ключа хеша.

При реализации hash для пользовательского класса рекомендуется использовать Array#hash с именем класса и значениями, важными для экземпляра; это позволяет воспользоваться логикой данного метода для безопасного и эффективного вычисления хеш-значения:

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

Хеш-значение может отличаться при разных вызовах и реализациях Ruby. Если вам нужны стабильные идентификаторы, подобные хешам, для разных запусков и реализаций Ruby, используйте специальный метод для их генерации.

inspect → string Показать исходный код
static VALUE
rb_obj_inspect(VALUE obj)
{
    VALUE ivars = rb_check_funcall(obj, id_instance_variables_to_inspect, 0, 0);
    st_index_t n = 0;
    if (UNDEF_P(ivars) || NIL_P(ivars)) {
        n = rb_ivar_count(obj);
        ivars = Qnil;
    }
    else if (RB_TYPE_P(ivars, T_ARRAY)) {
        n = RARRAY_LEN(ivars);
    }
    else {
        rb_raise(
            rb_eTypeError,
            "Expected #instance_variables_to_inspect to return an Array or nil, but it returned %"PRIsVALUE,
            rb_obj_class(ivars)
        );
    }

    if (n > 0) {
        VALUE c = rb_class_name(CLASS_OF(obj));
        VALUE args[2] = {
            rb_sprintf("-<%"PRIsVALUE":%p", c, (void*)obj),
            ivars
        };
        return rb_exec_recursive(inspect_obj, obj, (VALUE)args);
    }
    else {
        return rb_any_to_s(obj);
    }
}

Возвращает строку, содержащую удобное для чтения представление obj. По умолчанию inspect показывает имя класса объекта, закодированный адрес в памяти и список переменных экземпляра с их значениями (вызывая inspect для каждой из них). Пользовательские классы должны переопределять этот метод, чтобы обеспечить более подходящее представление obj. При переопределении метод должен возвращать строку с кодировкой, совместимой с используемой по умолчанию внешней кодировкой.

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

class Foo
end
Foo.new.inspect                  #=> "#<Foo:0x0300c868>"

class Bar
  def initialize
    @bar = 1
  end
end
Bar.new.inspect                  #=> "#<Bar:0x0300c868 @bar=1>"

Если объект obj отвечает на instance_variables_to_inspect, в строку inspect будут включены только переменные экземпляра, перечисленные в возвращаемом массиве.

class DatabaseConfig
  def initialize(host, user, password)
    @host = host
    @user = user
    @password = password
  end

private
  def instance_variables_to_inspect = [:@host, :@user]
end

conf = DatabaseConfig.new("localhost", "root", "hunter2")
conf.inspect #=> #<DatabaseConfig:0x0000000104def350 @host="localhost", @user="root">
instance_of?(class) → true or false Показать исходный код
VALUE
rb_obj_is_instance_of(VALUE obj, VALUE c)
{
    c = class_or_module_required(c);
    return RBOOL(rb_obj_class(obj) == c);
}

Возвращает true, если obj является экземпляром указанного класса. См. также Object#kind_of?.

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
static VALUE
rb_obj_ivar_defined(VALUE obj, VALUE iv)
{
    ID id = id_for_var(obj, iv, instance);

    if (!id) {
        return Qfalse;
    }
    return rb_ivar_defined(obj, id);
}

Возвращает true, если указанная переменная экземпляра определена в obj. Аргументы типа String преобразуются в символы.

class Fred
  def initialize(p1, p2)
    @a, @b = p1, p2
  end
end
fred = Fred.new('cat', 99)
fred.instance_variable_defined?(:@a)    #=> true
fred.instance_variable_defined?("@b")   #=> true
fred.instance_variable_defined?("@c")   #=> false
instance_variable_get(symbol) → obj Показать исходный код
instance_variable_get(string) → obj
static VALUE
rb_obj_ivar_get(VALUE obj, VALUE iv)
{
    ID id = id_for_var(obj, iv, instance);

    if (!id) {
        return Qnil;
    }
    return rb_ivar_get(obj, id);
}

Возвращает значение указанной переменной экземпляра или nil, если переменная экземпляра не задана. Для обычных переменных экземпляра в имени переменной следует указывать часть @. Если переданный символ недопустим в качестве имени переменной экземпляра, возникает исключение NameError. Аргументы типа String преобразуются в символы.

class Fred
  def initialize(p1, p2)
    @a, @b = p1, p2
  end
end
fred = Fred.new('cat', 99)
fred.instance_variable_get(:@a)    #=> "cat"
fred.instance_variable_get("@b")   #=> 99
instance_variable_set(symbol, obj) → obj Показать исходный код
instance_variable_set(string, obj) → obj
static VALUE
rb_obj_ivar_set_m(VALUE obj, VALUE iv, VALUE val)
{
    ID id = id_for_var(obj, iv, instance);
    if (!id) id = rb_intern_str(iv);
    return rb_ivar_set(obj, id, val);
}

Устанавливает для переменной экземпляра с именем symbol указанное значение объекта. Это может обойти инкапсуляцию, предусмотренную автором класса, поэтому использовать этот метод следует осторожно. Переменная не обязана существовать до вызова метода. Если имя переменной экземпляра передано в виде строки, эта строка преобразуется в символ.

class Fred
  def initialize(p1, p2)
    @a, @b = p1, p2
  end
end
fred = Fred.new('cat', 99)
fred.instance_variable_set(:@a, 'dog')   #=> "dog"
fred.instance_variable_set(:@c, 'cat')   #=> "cat"
fred.inspect                             #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"
instance_variables → array Показать исходный код
VALUE
rb_obj_instance_variables(VALUE obj)
{
    VALUE ary;

    ary = rb_ary_new();
    rb_ivar_foreach(obj, ivar_i, ary);
    return ary;
}

Возвращает массив имен переменных экземпляра получателя. Обратите внимание: простое определение метода доступа не создает соответствующую переменную экземпляра.

class Fred
  attr_accessor :a1
  def initialize
    @iv = 3
  end
end
Fred.new.instance_variables   #=> [:@iv]
is_a?(class) → true or false

Возвращает true, если class является классом obj, одним из суперклассов obj или модулем, подключенным к obj.

module M;    end
class A
  include M
end
class B < A; end
class C < B; end

b = B.new
b.is_a? A          #=> true
b.is_a? B          #=> true
b.is_a? C          #=> false
b.is_a? M          #=> true

b.kind_of? A       #=> true
b.kind_of? B       #=> true
b.kind_of? C       #=> false
b.kind_of? M       #=> true
Псевдоним для: kind_of?
itself → obj Показать исходный код
static VALUE
rb_obj_itself(VALUE obj)
{
    return obj;
}

Возвращает получателя.

string = "my string"
string.itself.object_id == string.object_id   #=> true
kind_of?(class) → true or false Показать исходный код
VALUE
rb_obj_is_kind_of(VALUE obj, VALUE c)
{
    VALUE cl = CLASS_OF(obj);

    RUBY_ASSERT(RB_TYPE_P(cl, T_CLASS));

    // Fastest path: If the object's class is an exact match we know `c` is a
    // class without checking type and can return immediately.
    if (cl == c) return Qtrue;

    // Note: YJIT needs this function to never allocate and never raise when
    // `c` is a class or a module.

    if (LIKELY(RB_TYPE_P(c, T_CLASS))) {
        // Fast path: Both are T_CLASS
        return class_search_class_ancestor(cl, c);
    }
    else if (RB_TYPE_P(c, T_ICLASS)) {
        // First check if we inherit the includer
        // If we do we can return true immediately
        VALUE includer = RCLASS_INCLUDER(c);
        if (cl == includer) return Qtrue;

        // Usually includer is a T_CLASS here, except when including into an
        // already included Module.
        // If it is a class, attempt the fast class-to-class check and return
        // true if there is a match.
        if (RB_TYPE_P(includer, T_CLASS) && class_search_class_ancestor(cl, includer))
            return Qtrue;

        // We don't include the ICLASS directly, so must check if we inherit
        // the module via another include
        return RBOOL(class_search_ancestor(cl, RCLASS_ORIGIN(c)));
    }
    else if (RB_TYPE_P(c, T_MODULE)) {
        // Slow path: check each ancestor in the linked list and its method table
        return RBOOL(class_search_ancestor(cl, RCLASS_ORIGIN(c)));
    }
    else {
        rb_raise(rb_eTypeError, "class or module required");
        UNREACHABLE_RETURN(Qfalse);
    }
}

Возвращает true, если class является классом obj, одним из суперклассов obj или модулем, подключенным к obj.

module M;    end
class A
  include M
end
class B < A; end
class C < B; end

b = B.new
b.is_a? A          #=> true
b.is_a? B          #=> true
b.is_a? C          #=> false
b.is_a? M          #=> true

b.kind_of? A       #=> true
b.kind_of? B       #=> true
b.kind_of? C       #=> false
b.kind_of? M       #=> true
Также имеет псевдоним: is_a?
method(sym) → method Показать исходный код
VALUE
rb_obj_method(VALUE obj, VALUE vid)
{
    return obj_method(obj, vid, FALSE);
}

Ищет в obj метод с указанным именем, используя объект в качестве получателя, и возвращает объект Method (или вызывает исключение NameError). Объект Method действует как замыкание в экземпляре объекта obj, поэтому переменные экземпляра и значение self остаются доступными.

class Demo
  def initialize(n)
    @iv = n
  end
  def hello()
    "Hello, @iv = #{@iv}"
  end
end

k = Demo.new(99)
m = k.method(:hello)
m.call   #=> "Hello, @iv = 99"

l = Demo.new('Fred')
m = l.method("hello")
m.call   #=> "Hello, @iv = Fred"

Обратите внимание, что Method реализует метод to_proc, а значит, его можно использовать с итераторами.

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

out = File.open('test.txt', 'w')
[ 1, 2, 3 ].each(&out.method(:puts)) # => prints 3 lines to file

require 'date'
%w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
#=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
methods(regular=true) → array Показать исходный код
VALUE
rb_obj_methods(int argc, const VALUE *argv, VALUE obj)
{
    rb_check_arity(argc, 0, 1);
    if (argc > 0 && !RTEST(argv[0])) {
        return rb_obj_singleton_methods(argc, argv, obj);
    }
    return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
}

Возвращает список имен публичных и защищенных методов объекта obj. В список входят все методы, доступные в предках obj. Если необязательный параметр равен false, возвращается массив публичных и защищенных методов singleton объекта obj; методы из модулей, подключенных к obj, в массив не включаются.

class Klass
  def klass_method()
  end
end
k = Klass.new
k.methods[0..9]    #=> [:klass_method, :nil?, :===,
                   #    :==~, :!, :eql?
                   #    :hash, :<=>, :class, :singleton_class]
k.methods.length   #=> 56

k.methods(false)   #=> []
def k.singleton_method; end
k.methods(false)   #=> [:singleton_method]

module M123; def m123; end end
k.extend M123
k.methods(false)   #=> [:singleton_method]
nil? → true or false Показать исходный код
VALUE
rb_false(VALUE obj)
{
    return Qfalse;
}

Только объект nil отвечает true на nil?.

Object.new.nil?   #=> false
nil.nil?          #=> true
__id__ → integer Показать исходный код
object_id → integer
VALUE
rb_obj_id(VALUE obj)
{
    /* If obj is an immediate, the object ID is obj directly converted to a Numeric.
     * Otherwise, the object ID is a Numeric that is a non-zero multiple of
     * (RUBY_IMMEDIATE_MASK + 1) which guarantees that it does not collide with
     * any immediates. */
    return rb_find_object_id(rb_gc_get_objspace(), obj, object_id);
}

Возвращает целочисленный идентификатор для obj.

При каждом вызове object_id для заданного объекта возвращается одно и то же число, и ни у каких двух существующих объектов идентификаторы не совпадают.

Примечание: некоторые объекты встроенных классов повторно используются для оптимизации. Это относится к непосредственным значениям и замороженным строковым литералам.

BasicObject реализует __id__, а Kernel реализует object_id.

Непосредственные значения передаются не по ссылке, а по значению: nil, true, false, Fixnum, символы и некоторые значения 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 Показать исходный код
VALUE
rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj)
{
    return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
}

Возвращает список закрытых методов, доступных объекту obj. Если параметр all установлен в false, будут перечислены только методы самого получателя.

protected_methods(all=true) → array Показать исходный код
VALUE
rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj)
{
    return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
}

Возвращает список защищенных методов, доступных объекту obj. Если параметр all установлен в false, будут перечислены только методы самого получателя.

public_method(sym) → method Показать исходный код
VALUE
rb_obj_public_method(VALUE obj, VALUE vid)
{
    return obj_method(obj, vid, TRUE);
}

Подобно method, ищет только публичные методы.

public_methods(all=true) → array Показать исходный код
VALUE
rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj)
{
    return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
}

Возвращает список публичных методов, доступных объекту obj. Если параметр all установлен в false, будут перечислены только методы самого получателя.

public_send(symbol [, args...]) → obj Показать исходный код
public_send(string [, args...]) → obj
static VALUE
rb_f_public_send(int argc, VALUE *argv, VALUE recv)
{
    return send_internal_kw(argc, argv, recv, CALL_PUBLIC);
}

Вызывает метод, указанный в symbol, передавая ему заданные аргументы. В отличие от send, public_send вызывает только публичные методы. Если метод указан строкой, она преобразуется в символ.

1.public_send(:puts, "hello")  # causes NoMethodError
remove_instance_variable(symbol) → obj Показать исходный код
remove_instance_variable(string) → obj
VALUE
rb_obj_remove_instance_variable(VALUE obj, VALUE name)
{
    const ID id = id_for_var(obj, name, an, instance);

    // Frozen check comes here because it's expected that we raise a
    // NameError (from the id_for_var check) before we raise a FrozenError
    rb_check_frozen(obj);

    if (id) {
        VALUE val = rb_ivar_delete(obj, id, Qundef);

        if (!UNDEF_P(val)) return val;
    }

    rb_name_err_raise("instance variable %1$s not defined",
                      obj, name);
    UNREACHABLE_RETURN(Qnil);
}

Удаляет из obj указанную переменную экземпляра и возвращает её значение. Имя можно передать в виде символа или строки.

class Dummy
  attr_reader :var
  def initialize
    @var = 99
  end
  def remove
    remove_instance_variable(:@var)
  end
end
d = Dummy.new
d.var      #=> 99
d.remove   #=> 99
d.var      #=> nil
respond_to?(symbol, include_all=false) → true or false Показать исходный код
respond_to?(string, include_all=false) → true or false
static VALUE
obj_respond_to(int argc, VALUE *argv, VALUE obj)
{
    VALUE mid, priv;
    ID id;
    rb_execution_context_t *ec = GET_EC();

    rb_scan_args(argc, argv, "11", &mid, &priv);
    if (!(id = rb_check_id(&mid))) {
        VALUE ret = basic_obj_respond_to_missing(ec, CLASS_OF(obj), obj,
                                                 rb_to_symbol(mid), priv);
        if (UNDEF_P(ret)) ret = Qfalse;
        return ret;
    }
    return  RBOOL(basic_obj_respond_to(ec, obj, id, !RTEST(priv)));
}

Возвращает true, если obj поддерживает указанный метод. Закрытые и защищённые методы включаются в поиск, только если необязательный второй параметр имеет значение true.

Если метод не реализован, например Process.fork в Windows, File.lchmod в GNU/Linux и т. д., возвращается false.

Если метод не определён, вызывается метод respond_to_missing? и возвращается его результат.

Если имя метода задано строкой, она преобразуется в символ.

respond_to_missing?(symbol, include_all) → true or false Показать исходный код
respond_to_missing?(string, include_all) → true or false
static VALUE
obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
{
    return Qfalse;
}

НЕ ВЫЗЫВАЙТЕ ЭТОТ МЕТОД НАПРЯМУЮ.

Метод-перехватчик, возвращающий информацию о том, может ли obj отвечать на вызов метода id.

Если имя метода задано строкой, она преобразуется в символ.

См. respond_to? и пример для BasicObject.

send(symbol [, args...]) → obj Показать исходный код
__send__(symbol [, args...]) → obj
send(string [, args...]) → obj
__send__(string [, args...]) → obj
VALUE
rb_f_send(int argc, VALUE *argv, VALUE recv)
{
    return send_internal_kw(argc, argv, recv, CALL_FCALL);
}

Вызывает метод, указанный в symbol, передавая ему заданные аргументы. Если метод указан строкой, она преобразуется в символ.

BasicObject реализует __send__, а Kernel реализует send. __send__ безопаснее, чем send, если у obj есть метод с тем же именем, что и у Socket. См. также 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 Показать исходный код
static VALUE
rb_obj_singleton_class(VALUE obj)
{
    return rb_singleton_class(obj);
}

Возвращает класс-синглтон объекта obj. Если у obj нет класса-синглтона, этот метод создаёт его.

Если obj — nil, true или false, метод возвращает соответственно NilClass, TrueClass или FalseClass. Если obj — Integer, Float или Symbol, возникает исключение TypeError.

Object.new.singleton_class  #=> #<Class:#<Object:0xb7ce1e24>>
String.singleton_class      #=> #<Class:String>
nil.singleton_class         #=> NilClass
singleton_method(sym) → method Показать исходный код
VALUE
rb_obj_singleton_method(VALUE obj, VALUE vid)
{
    VALUE sc = rb_singleton_class_get(obj);
    VALUE klass;
    ID id = rb_check_id(&vid);

    if (NIL_P(sc) ||
        NIL_P(klass = RCLASS_ORIGIN(sc)) ||
        !NIL_P(rb_special_singleton_class(obj))) {
        /* goto undef; */
    }
    else if (! id) {
        VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
        if (m) return m;
        /* else goto undef; */
    }
    else {
        VALUE args[2] = {obj, vid};
        VALUE ruby_method = rb_rescue(rb_obj_singleton_method_lookup, (VALUE)args, rb_obj_singleton_method_lookup_fail, Qfalse);
        if (ruby_method) {
            struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(ruby_method);
            VALUE lookup_class = RBASIC_CLASS(obj);
            VALUE stop_class = rb_class_superclass(sc);
            VALUE method_class = method->iclass;

            /* Determine if method is in singleton class, or module included in or prepended to it */
            do {
                if (lookup_class == method_class) {
                    return ruby_method;
                }
                lookup_class = RCLASS_SUPER(lookup_class);
            } while (lookup_class && lookup_class != stop_class);
        }
    }

  /* undef: */
    vid = ID2SYM(id);
    rb_name_err_raise("undefined singleton method '%1$s' for '%2$s'",
                      obj, vid);
    UNREACHABLE_RETURN(Qundef);
}

Подобно method, выполняет поиск только методов-синглтонов.

class Demo
  def initialize(n)
    @iv = n
  end
  def hello()
    "Hello, @iv = #{@iv}"
  end
end

k = Demo.new(99)
def k.hi
  "Hi, @iv = #{@iv}"
end
m = k.singleton_method(:hi)
m.call   #=> "Hi, @iv = 99"
m = k.singleton_method(:hello) #=> NameError
singleton_methods(all=true) → array Показать исходный код
VALUE
rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
{
    VALUE ary, klass, origin;
    struct method_entry_arg me_arg;
    struct rb_id_table *mtbl;
    int recur = TRUE;

    if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]);
    if (RCLASS_SINGLETON_P(obj)) {
        rb_singleton_class(obj);
    }
    klass = CLASS_OF(obj);
    origin = RCLASS_ORIGIN(klass);
    me_arg.list = st_init_numtable();
    me_arg.recur = recur;
    if (klass && RCLASS_SINGLETON_P(klass)) {
        if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
        klass = RCLASS_SUPER(klass);
    }
    if (recur) {
        while (klass && (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS))) {
            if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg);
            klass = RCLASS_SUPER(klass);
        }
    }
    ary = rb_ary_new2(me_arg.list->num_entries);
    st_foreach(me_arg.list, ins_methods_i, ary);
    st_free_table(me_arg.list);

    return ary;
}

Возвращает массив имён методов-синглтонов объекта obj. Если необязательный параметр all имеет значение true, в список включаются методы модулей, подключённых к obj. Возвращаются только открытые и защищённые методы-синглтоны.

module Other
  def three() end
end

class Single
  def Single.four() end
end

a = Single.new

def a.one()
end

class << a
  include Other
  def two()
  end
end

Single.singleton_methods    #=> [:four]
a.singleton_methods(false)  #=> [:two, :one]
a.singleton_methods         #=> [:two, :one, :three]
to_enum(method = :each, *args) → enum Показать исходный код
to_enum(method = :each, *args) {|*args| block} → enum
static VALUE
obj_to_enum(int argc, VALUE *argv, VALUE obj)
{
    VALUE enumerator, meth = sym_each;

    if (argc > 0) {
        --argc;
        meth = *argv++;
    }
    enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
    if (rb_block_given_p()) {
        RB_OBJ_WRITE(enumerator, &enumerator_ptr(enumerator)->size, rb_block_proc());
    }
    return enumerator;
}

Создаёт новый Enumerator, который выполняет перечисление, вызывая method для obj и передавая ему args, если они заданы. Значения перечислителя — это значения, возвращённые блоком метода.

Если передан блок, он используется для вычисления размера перечислителя без необходимости его обхода (см. Enumerator#size).

Примеры

str = "xyz"

enum = str.enum_for(:each_byte)
enum.each { |b| puts b }
# => 120
# => 121
# => 122

# protect an array from being modified by some_method
a = [1, 2, 3]
some_method(a.to_enum)

# String#split in block form is more memory-effective:
very_large_string.split("|") { |chunk| return chunk if chunk.include?('DATE') }
# This could be rewritten more idiomatically with to_enum:
very_large_string.to_enum(:split, "|").lazy.grep(/DATE/).first

При определении методов для универсального Enumerable принято вызывать to_enum на случай, если блок не передан.

Ниже приведён пример с передачей параметров и блоком для вычисления размера:

module Enumerable
  # a generic method to repeat the values of any enumerable
  def repeat(n)
    raise ArgumentError, "#{n} is negative!" if n < 0
    unless block_given?
      return to_enum(__method__, n) do # __method__ is :repeat here
        sz = size     # Call size and multiply by n...
        sz * n if sz  # but return nil if size itself is nil
      end
    end
    each do |*val|
      n.times { yield *val }
    end
  end
end

%i[hello world].repeat(2) { |w| puts w }
  # => Prints 'hello', 'hello', 'world', 'world'
enum = (1..14).repeat(3)
  # => returns an Enumerator when called without a block
enum.first(4) # => [1, 1, 1, 2]
enum.size # => 42
Также имеет псевдоним: enum_for
to_s → string Показать исходный код
VALUE
rb_any_to_s(VALUE obj)
{
    VALUE str;
    VALUE cname = rb_class_name(CLASS_OF(obj));

    str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj);

    return str;
}

Возвращает строковое представление объекта obj. Реализация to_s по умолчанию выводит класс объекта и закодированное представление его идентификатора. Особый случай — объект верхнего уровня, являющийся начальным контекстом выполнения программ Ruby: он возвращает «main».

to_yaml(options = {}) Показать исходный код
# File ext/psych/lib/psych/core_ext.rb, line 12
def to_yaml options = {}
  Psych.dump self, options
end

Преобразует объект в YAML. Дополнительные сведения о доступных options см. в описании Psych.dump.

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API