Spec-Zone.ru › Ruby 2.6

класс BasicObject

Родитель:

BasicObject — это базовый класс для всех классов в Ruby. Это явный пустой класс.

BasicObject может использоваться для создания иерархий объектов, независимых от иерархии объектов Ruby, таких как объекты-прокси, как класс Delegator, или в других случаях, когда необходимо избежать загрязнения пространства имён методами и классами Ruby.

Чтобы избежать загрязнения пространства имён BasicObject для других пользователей, следует создать соответствующий подкласс BasicObject, а не напрямую изменять BasicObject:

class MyObjectSystem < BasicObject
end

BasicObject не включает Kernel (для методов, таких как puts) и BasicObject находится вне пространства имён стандартной библиотеки, поэтому общие классы не будут найдены без использования полного пути к классу.

Существуют различные стратегии, которые могут использоваться для предоставления полезных частей стандартной библиотеки подклассам BasicObject. Подкласс может include Kernel для получения puts, exit, и т. д. Можно создать и включить модуль, подобный Kernel, или использовать делегирование через method_missing:

class MyObjectSystem < BasicObject
  DELEGATE = [:puts, :p]

  def method_missing(name, *args, &block)
    super unless DELEGATE.include? name
    ::Kernel.send(name, *args, &block)
  end

  def respond_to_missing?(name, include_private = false)
    DELEGATE.include?(name) or super
  end
end

Доступ к классам и модулям из стандартной библиотеки Ruby можно получить в подклассе BasicObject, ссылаясь на нужную константу из корня, как ::File или ::Enumerator. Как и method_missing, можно использовать const_missing для делегирования поиска констант в Object:

class MyObjectSystem < BasicObject
  def self.const_missing(name)
    ::Object.const_get(name)
  end
end

Методы публичного класса

new() Показать исходный код
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Не документировано

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

!obj → true или false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_obj_not(VALUE obj)
{
    return RTEST(obj) ? Qfalse : Qtrue;
}

Логическое отрицание.

obj != other → true или false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_obj_not_equal(VALUE obj1, VALUE obj2)
{
    VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
    return RTEST(result) ? Qfalse : Qtrue;
}

Возвращает true, если два объекта не равны, в противном случае false.

obj == other → true или false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

Равенство — На уровне 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 для проверки равенства членов. Для объектов класса Object, eql? является синонимом ==. Подклассы обычно продолжают эту традицию, алиазируя eql? с их переопределённым методом ==, но есть исключения. Например, типы Numeric выполняют преобразование типов через ==, но не через eql?, поэтому:

1 == 1.0     #=> true
1.eql? 1.0   #=> false
__id__ → целое число Показать исходный код
object_id → целое число
VALUE
rb_obj_id(VALUE obj)
{
    /*
     *                32-bit VALUE space
     *          MSB ------------------------ LSB
     *  false   00000000000000000000000000000000
     *  true    00000000000000000000000000000010
     *  nil     00000000000000000000000000000100
     *  undef   00000000000000000000000000000110
     *  symbol  ssssssssssssssssssssssss00001110
     *  object  oooooooooooooooooooooooooooooo00        = 0 (mod sizeof(RVALUE))
     *  fixnum  fffffffffffffffffffffffffffffff1
     *
     *                    object_id space
     *                                       LSB
     *  false   00000000000000000000000000000000
     *  true    00000000000000000000000000000010
     *  nil     00000000000000000000000000000100
     *  undef   00000000000000000000000000000110
     *  symbol   000SSSSSSSSSSSSSSSSSSSSSSSSSSS0        S...S % A = 4 (S...S = s...s * A + 4)
     *  object   oooooooooooooooooooooooooooooo0        o...o % A = 0
     *  fixnum  fffffffffffffffffffffffffffffff1        bignum if required
     *
     *  where A = sizeof(RVALUE)/4
     *
     *  sizeof(RVALUE) is
     *  20 if 32-bit, double is 4-byte aligned
     *  24 if 32-bit, double is 8-byte aligned
     *  40 if 64-bit
     */
    if (STATIC_SYM_P(obj)) {
        return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
    }
    else if (FLONUM_P(obj)) {
#if SIZEOF_LONG == SIZEOF_VOIDP
        return LONG2NUM((SIGNED_VALUE)obj);
#else
        return LL2NUM((SIGNED_VALUE)obj);
#endif
    }
    else if (SPECIAL_CONST_P(obj)) {
        return LONG2NUM((SIGNED_VALUE)obj);
    }
    return nonspecial_obj_id(obj);
}

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

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

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

Непосредственные значения не передаются по ссылке, а передаются по значению: nil, true, false, Fixnums, Symbols и некоторые Floats.

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
send(символ [, args...]) → obj Показать исходный код
__send__(символ [, args...]) → obj
send(строка [, args...]) → obj
__send__(строка [, args...]) → obj
VALUE
rb_f_send(int argc, VALUE *argv, VALUE recv)
{
    return send_internal(argc, argv, recv, CALL_FCALL);
}

Вызывает метод, идентифицированный символом, передавая ему любые указанные аргументы. Можно использовать __send__, если имя send конфликтует с существующим методом в объекте. Если метод идентифицируется строкой, строка преобразуется в символ.

class Klass
  def hello(*args)
    "Hello " + args.join(' ')
  end
end
k = Klass.new
k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
equal?(other) → true или false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

Равенство — На уровне 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 для проверки равенства членов. Для объектов класса Object, eql? является синонимом ==. Подклассы обычно продолжают эту традицию, алиазируя eql? с их переопределённым методом ==, но есть исключения. Например, типы Numeric выполняют преобразование типов через ==, но не через eql?, поэтому:

1 == 1.0     #=> true
1.eql? 1.0   #=> false
instance_eval(строка [, имя_файла [, номер_строки]] ) → obj Показать исходный код
instance_eval {|объект| блок } → obj
VALUE
rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
{
    VALUE klass = singleton_class_for_eval(self);
    return specific_eval(argc, argv, klass, self);
}

Вычисляет строку, содержащую Ruby-код, или данный блок в контексте получателя (объект). Для установки контекста переменная self устанавливается в объект во время выполнения кода, предоставляя коду доступ к переменным экземпляра и закрытым методам объекта.

Если instance_eval получает блок, объект также передаётся в качестве единственного аргумента блока.

Если instance_eval получает строку, необязательные второй и третий параметры обеспечивают имя файла и начальный номер строки, которые используются при сообщении об ошибках компиляции.

class KlassWithSecret
  def initialize
    @secret = 99
  end
  private
  def the_secret
    "Ssssh! The secret is #{@secret}."
  end
end
k = KlassWithSecret.new
k.instance_eval { @secret }          #=> 99
k.instance_eval { the_secret }       #=> "Ssssh! The secret is 99."
k.instance_eval {|obj| obj == self } #=> true
instance_exec(арг...) {|переменная...| блок } → obj Показать исходный код
VALUE
rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
{
    VALUE klass = singleton_class_for_eval(self);
    return yield_under(klass, self, argc, argv);
}

Выполняет данный блок в контексте получателя (объект). Для установки контекста переменная self устанавливается в объект во время выполнения кода, предоставляя коду доступ к переменным экземпляра. Аргументы передаются как параметры блока.

class KlassWithSecret
  def initialize
    @secret = 99
  end
end
k = KlassWithSecret.new
k.instance_exec(5) {|x| @secret+x }   #=> 104

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

method_missing(символ [, *args] ) → результат Показать исходный код
static VALUE
rb_method_missing(int argc, const VALUE *argv, VALUE obj)
{
    rb_execution_context_t *ec = GET_EC();
    raise_method_missing(ec, argc, argv, obj, ec->method_missing_reason);
    UNREACHABLE_RETURN(Qnil);
}

Вызывается Ruby, когда объекту отправляется сообщение, которое он не может обработать. Символ — это символ вызываемого метода, а args — любые аргументы, которые были ему переданы. По умолчанию интерпретатор генерирует ошибку при вызове этого метода. Однако можно переопределить метод для предоставления более динамичного поведения. Если решено, что определённый метод не должен обрабатываться, то должен быть вызван super, чтобы предки могли обработать отсутствующий метод. Пример ниже создаёт класс Roman, который отвечает на методы с именами, состоящими из римских цифр, возвращая соответствующие целочисленные значения.

class Roman
  def roman_to_int(str)
    # ...
  end
  def method_missing(methId)
    str = methId.id2name
    roman_to_int(str)
  end
end

r = Roman.new
r.iv      #=> 4
r.xxiii   #=> 23
r.mm      #=> 2000
singleton_method_added(символ) Показать исходный код
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

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

module Chatty
  def Chatty.singleton_method_added(id)
    puts "Adding #{id.id2name}"
  end
  def self.one()     end
  def two()          end
  def Chatty.three() end
end

вывод:

Adding singleton_method_added
Adding one
Adding three
singleton_method_removed(символ) Показать исходный код
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

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

module Chatty
  def Chatty.singleton_method_removed(id)
    puts "Removing #{id.id2name}"
  end
  def self.one()     end
  def two()          end
  def Chatty.three() end
  class << self
    remove_method :three
    remove_method :one
  end
end

вывод:

Removing three
Removing one
singleton_method_undefined(символ) Показать исходный код
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

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

module Chatty
  def Chatty.singleton_method_undefined(id)
    puts "Undefining #{id.id2name}"
  end
  def Chatty.one()   end
  class << self
     undef_method(:one)
  end
end

вывод:

Undefining one

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

Spec-Zone.ru

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