Spec-Zone.ru › Ruby 2.2

класс Struct

Родитель:
Объект
Включенные модули:
Enumerable

Класс Struct — удобный способ объединения нескольких атрибутов с помощью методов доступа, без необходимости написания явного класса.

Класс Struct генерирует новые подклассы, которые содержат набор членов и их значения. Для каждого члена создаются методы чтения и записи, аналогично Module#attr_accessor.

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end

dave = Customer.new("Dave", "123 Main")
dave.name     #=> "Dave"
dave.greeting #=> "Hello Dave!"

См. ::new для дополнительных примеров создания подклассов и экземпляров структур.

В описаниях методов параметр «member» относится к члену структуры, который является либо строкой в кавычках ("name") либо символом (:name).

Константы

Group

Group

Group — это Struct, доступный только при компиляции с HAVE_GETGRENT.

Структура содержит следующие члены:

name

содержит имя группы в виде строки.

passwd

содержит зашифрованный пароль в виде строки. Возвращает 'x', если доступ к паролю для группы недоступен; возвращает пустую строку, если пароль не нужен для получения членства в группе.

Требуется компиляция с HAVE_STRUCT_GROUP_GR_PASSWD.

gid

содержит числовой идентификатор группы в виде целого числа.

mem

представляет собой массив строк, содержащих короткие логины членов группы.

Passwd

Passwd

Passwd — это Struct, который содержит следующие члены:

name

содержит короткое имя входа пользователя в виде строки.

passwd

содержит зашифрованный пароль пользователя в виде строки. Возвращает 'x', если используются скрытые пароли. Возвращает '*', если пользователь не может войти с помощью пароля.

uid

содержит целочисленный идентификатор пользователя (uid).

gid

содержит целочисленный идентификатор группы (gid) основной группы пользователя.

dir

содержит путь к домашнему каталогу пользователя в виде строки.

shell

содержит путь к оболочке входа пользователя в виде строки.

Следующие члены ниже являются необязательными и требуют компиляции со специальными флагами:

gecos

содержит более подробное описание пользователя, например, полное имя. Некоторые Unix-системы предоставляют структурированную информацию в поле gecos, но это зависит от системы. Требуется компиляция с HAVE_STRUCT_PASSWD_PW_GECOS

change

время изменения пароля (целое число). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_CHANGE

quota

значение квоты (целое число). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_QUOTA

age

возраст пароля (целое число). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_AGE

class

класс доступа пользователя (строка). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_CLASS

comment

комментарий (строка). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_COMMENT

expire

время истечения срока действия учетной записи (целое число). Требуется компиляция с HAVE_STRUCT_PASSWD_PW_EXPIRE

Tms

Публичные методы класса

json_create(object) Показать исходный код
# File ext/json/lib/json/add/struct.rb, line 9
def self.json_create(object)
  new(*object['v'])
end

Десериализует строку JSON, создавая новый объект Struct со значениями v сериализованными с помощью to_json.

new([class_name] [, member_name]+>) → StructClass Показать исходный код
new([class_name] [, member_name]+>) {|StructClass| block } → StructClass
new(value, ...) → obj
StructClass[value, ...] → obj
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
    VALUE name, rest;
    long i;
    VALUE st;
    st_table *tbl;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    name = argv[0];
    if (SYMBOL_P(name)) {
        name = Qnil;
    }
    else {
        --argc;
        ++argv;
    }
    rest = rb_ident_hash_new();
    RBASIC_CLEAR_CLASS(rest);
    tbl = RHASH_TBL(rest);
    for (i=0; i<argc; i++) {
        VALUE mem = rb_to_symbol(argv[i]);
        if (st_insert(tbl, mem, Qtrue)) {
            rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
        }
    }
    rest = rb_hash_keys(rest);
    st_clear(tbl);
    RBASIC_CLEAR_CLASS(rest);
    if (NIL_P(name)) {
        st = anonymous_struct(klass);
    }
    else {
        st = new_struct(name, klass);
    }
    setup_struct(st, rest);
    if (rb_block_given_p()) {
        rb_mod_module_eval(0, 0, st);
    }

    return st;
}

Первые две формы используются для создания нового подкласса Struct class_name , который может содержать значение для каждого member_name. Этот подкласс может использоваться для создания экземпляров структуры, как любой другой класс.

Если class_name опущено, будет создан анонимный класс структуры. В противном случае, имя этой структуры будет отображаться как константа в классе Struct, поэтому оно должно быть уникальным для всех структур в системе и должно начинаться с заглавной буквы. Присвоение класса структуры константе также дает классу имя константы.

# Create a structure with a name under Struct
Struct.new("Customer", :name, :address)
#=> Struct::Customer
Struct::Customer.new("Dave", "123 Main")
#=> #<struct Struct::Customer name="Dave", address="123 Main">

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

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end
Customer.new("Dave", "123 Main").greeting  # => "Hello Dave!"

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

Последние две формы создают новый экземпляр подкласса структуры. Количество value параметров должно быть меньше или равно количеству атрибутов, определённых для структуры. Незаданные параметры по умолчанию nil. Передача большего количества параметров, чем атрибутов, вызовет исключение ArgumentError.

# Create a structure named by its constant
Customer = Struct.new(:name, :address)
#=> Customer
Customer.new("Dave", "123 Main")
#=> #<struct Customer name="Dave", address="123 Main">

Общедоступные методы экземпляров

struct == other → true или false Показать исходный код
static VALUE
rb_struct_equal(VALUE s, VALUE s2)
{
    if (s == s2) return Qtrue;
    if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
    if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
        rb_bug("inconsistent struct"); /* should never happen */
    }

    return rb_exec_recursive_paired(recursive_equal, s, s2, s2);
}

Равенство — Возвращает true если other имеет тот же подкласс структуры и имеет равные значения членов (в соответствии с Object#==).

Customer = Struct.new(:name, :address, :zip)
joe   = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
jane  = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
joe == joejr   #=> true
joe == jane    #=> false
struct[member] → anObject Показать исходный код
struct[index] → anObject
VALUE
rb_struct_aref(VALUE s, VALUE idx)
{
    long i;

    if (RB_TYPE_P(idx, T_SYMBOL)) {
        return rb_struct_aref_sym(s, idx);
    }
    else if (RB_TYPE_P(idx, T_STRING)) {
        ID id = rb_check_id(&idx);
        if (!id) {
            rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct",
                              QUOTE(idx));
        }
        return rb_struct_aref_sym(s, ID2SYM(id));
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT_LEN(s) + i;
    if (i < 0)
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    if (RSTRUCT_LEN(s) <= i)
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    return RSTRUCT_GET(s, i);
}

Ссылка на атрибут — Возвращает значение заданного члена структуры member или члена по заданному index. Вызывает NameError, если member не существует, и IndexError, если index выходит за пределы диапазона.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

joe["name"]   #=> "Joe Smith"
joe[:name]    #=> "Joe Smith"
joe[0]        #=> "Joe Smith"
struct[name] = obj → obj Показать исходный код
struct[index] = obj → obj
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
    long i;

    if (RB_TYPE_P(idx, T_SYMBOL)) {
        return rb_struct_aset_sym(s, idx, val);
    }
    if (RB_TYPE_P(idx, T_STRING)) {
        ID id = rb_check_id(&idx);
        if (!id) {
            rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct",
                              QUOTE(idx));
        }
        return rb_struct_aset_sym(s, ID2SYM(id), val);
    }

    i = NUM2LONG(idx);
    if (i < 0) i = RSTRUCT_LEN(s) + i;
    if (i < 0) {
        rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    }
    if (RSTRUCT_LEN(s) <= i) {
        rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
                 i, RSTRUCT_LEN(s));
    }
    rb_struct_modify(s);
    RSTRUCT_SET(s, i, val);
    return val;
}

Присвоение атрибута — Устанавливает значение заданного члена структуры member или члена по заданному index. Вызывает NameError, если name не существует, и IndexError, если index выходит за пределы диапазона.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

joe["name"] = "Luke"
joe[:zip]   = "90210"

joe.name   #=> "Luke"
joe.zip    #=> "90210"
as_json(*) Показать исходный код
# File ext/json/lib/json/add/struct.rb, line 15
def as_json(*)
  klass = self.class.name
  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
  {
    JSON.create_id => klass,
    'v'            => values,
  }
end

Возвращает хеш, который будет преобразован в объект JSON и представляет этот объект.

each {|obj| block } → struct Показать исходный код
each → an_enumerator
static VALUE
rb_struct_each(VALUE s)
{
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_yield(RSTRUCT_GET(s, i));
    }
    return s;
}

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

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|x| puts(x) }

Производит:

Joe Smith
123 Maple, Anytown NC
12345
each_pair {|sym, obj| block } → struct Показать исходный код
each_pair → an_enumerator
static VALUE
rb_struct_each_pair(VALUE s)
{
    VALUE members;
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    members = rb_struct_members(s);
    if (rb_block_arity() > 1) {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield_values(2, key, value);
        }
    }
    else {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield(rb_assoc_new(key, value));
        }
    }
    return s;
}

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

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each_pair {|name, value| puts("#{name} => #{value}") }

Производит:

name => Joe Smith
address => 123 Maple, Anytown NC
zip => 12345
eql?(other) → true или false Показать исходный код
static VALUE
rb_struct_eql(VALUE s, VALUE s2)
{
    if (s == s2) return Qtrue;
    if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
    if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
        rb_bug("inconsistent struct"); /* should never happen */
    }

    return rb_exec_recursive_paired(recursive_eql, s, s2, s2);
}

Равенство хеша — other и struct относятся к одному ключу хеша, если они имеют тот же подкласс структуры и имеют равные значения членов (в соответствии с Object#eql?).

hash → fixnum Показать исходный код
static VALUE
rb_struct_hash(VALUE s)
{
    long i, len;
    st_index_t h;
    VALUE n;
    const VALUE *ptr;

    h = rb_hash_start(rb_hash(rb_obj_class(s)));
    ptr = RSTRUCT_CONST_PTR(s);
    len = RSTRUCT_LEN(s);
    for (i = 0; i < len; i++) {
        n = rb_hash(ptr[i]);
        h = rb_hash_uint(h, NUM2LONG(n));
    }
    h = rb_hash_end(h);
    return INT2FIX(h);
}

Возвращает значение хеша, основанное на содержимом этой структуры (см. Object#hash).

См. также Object#hash.

to_s → строка Показать исходный код
inspect → строка
static VALUE
rb_struct_inspect(VALUE s)
{
    return rb_exec_recursive(inspect_struct, s, 0);
}

Описывает содержимое этой структуры в строке.

Также алиас: to_s
length → fixnum Показать исходный код
static VALUE
rb_struct_size(VALUE s)
{
    return LONG2FIX(RSTRUCT_LEN(s));
}

Возвращает количество членов структуры.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length   #=> 3
members → массив Показать исходный код
static VALUE
rb_struct_members_m(VALUE obj)
{
    return rb_struct_s_members_m(rb_obj_class(obj));
}

Возвращает члены структуры в виде массива символов:

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.members   #=> [:name, :address, :zip]
select {|i| block } → массив Показать исходный код
select → an_enumerator
static VALUE
rb_struct_select(int argc, VALUE *argv, VALUE s)
{
    VALUE result;
    long i;

    rb_check_arity(argc, 0, 0);
    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    result = rb_ary_new();
    for (i = 0; i < RSTRUCT_LEN(s); i++) {
        if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
            rb_ary_push(result, RSTRUCT_GET(s, i));
        }
    }

    return result;
}

Возвращает каждый член структуры блоку и возвращает массив значений членов из struct, для которых данный блок возвращает значение true (эквивалентно Enumerable#select).

Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| (v % 2).zero? }   #=> [22, 44, 66]
size → fixnum Показать исходный код
static VALUE
rb_struct_size(VALUE s)
{
    return LONG2FIX(RSTRUCT_LEN(s));
}

Возвращает количество членов структуры.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length   #=> 3
to_a → массив Показать исходный код
static VALUE
rb_struct_to_a(VALUE s)
{
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
}

Возвращает значения для этой структуры в виде массива.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1]   #=> "123 Maple, Anytown NC"
to_h → хеш Показать исходный код
static VALUE
rb_struct_to_h(VALUE s)
{
    VALUE h = rb_hash_new();
    VALUE members = rb_struct_members(s);
    long i;

    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i));
    }
    return h;
}

Возвращает хеш, содержащий имена и значения для членов структуры.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_h[:address]   #=> "123 Maple, Anytown NC"
to_json(*args) Показать исходный код
# File ext/json/lib/json/add/struct.rb, line 26
def to_json(*args)
  as_json.to_json(*args)
end

Хранит имя класса (Struct) со значениями Struct v как строку JSON. Поддерживаются только именованные структуры.

to_s()
Псевдоним для: inspect
values → массив Показать исходный код
static VALUE
rb_struct_to_a(VALUE s)
{
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
}

Возвращает значения для этой структуры в виде массива.

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1]   #=> "123 Maple, Anytown NC"
values_at(selector, ...) → an_array Показать исходный код
static VALUE
rb_struct_values_at(int argc, VALUE *argv, VALUE s)
{
    return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
}

Возвращает значения членов структуры для каждого selector в виде массива. selector может быть смещением Integer или диапазоном смещений Range (как в Array#values_at).

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.values_at 0, 2 #=> ["Joe Smith", 12345]

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