Въпроси и мнения след лекция 1

  1. Днес се наложи да минем по-бързичко през някои от слайдовете, но ще ни простите, а ние ще се опитаме да не го правим отново (:

    Ако има:

    • Незададени въпроси
    • Нещо неясно
    • Нещо ясно, за което искате да поговорите
    • Критика към воденето на лекцията или съдържанието
    • Неизказани хвалби
    • Или каквото и да е друго, но свързано с лекция 1

    Пишете тук или отворете нова тема (ако смятате, че е нужно).

  2. @Станимир,

    Първо да изясним за кои числа говорим. Числата от тип Fixnum се интернират. Това са сравнително малки цели числа. Можеш да си ги представяш като integer от други езици. Числата с плаваща запетая също се интернират.

    Всъщност Fixnum, Symbol, true, false и nil са immediate values. Това ще рече, че вместо да се пазят на някакво място в паметта и да има указател към тях в променливата, те се съхраняват в самата памет за указателя. Тоест когато напишеш number = 42, вместо да се насочи указателят number към клетката в паметта, където е 42 - 42 се записва директно в number.

    Така практически не се налага да се заделя допълнителна памет и достъпът до стойностите на подобни променливи става по-бърз. Това е така, защото не се налага да се дереферира указател. Същото важи и за символите. Сравнението не е основната причина, а по-скоро следствие от това, че достъпът до тези стойности е по-бърз. Ако искаш да разбереш повече детайли виж този отговор в StackOverflow.

    Това е имплементационен детайл на MRI (C интерпретатора, който ние ползваме). Интересно е, но няма нужда да се знае, за да работим добре с езика. Това е просто една оптимизация, която се използва за подобряване на производителността.

  3. Накратко

    целите числа са вероятно най-често използваният "вид" обекти в повечето програми.

    Такива детайли са специфични за имплементацията, така че тук се има предвид главно MRI(референтната имплементация, която почти всички ползваме)

    В този смисъл, интернирането им спестява

    • памет (не се създава отделна C структура за всяко число)
    • време (спестяват се проследявания на pointer-и, защото стойността се взима директно)

    Имплементационни детайли и C магия

    Начинът, по който това работи в MRI е сравнително прост. Най-общо казано, на всеки Ruby обект съответства стойност от C типа VALUE. Най-елементарното решение в една имплементация би било тази стойност да е просто pointer към C структура, съдържаща данните на обекта. В MRI това е почти така, но не и за няколко специални типа стойности.

    VALUE e дефинирано като typedef uintptr_t VALUE, тоест неотрицателно цяло число, което е със size, достатъчен за да съдържа адреса на pointer. Това число е точно #object_id на един обект в Руби, така че лесно може да се поиграе и да се разгледа в irb.

    Всеки път, когато MRI се опита да интерпретира VALUE стойност, то проверява вътрешния и интерпретатор-специфичен клас, който е закодиран чрез определени битове в това число. Специфично, Fixnum обектите са точно тези, чиито последен бит е 1. Когато такъв обект бъде засечен, още един бит кодира знака, и останалите 30 на 32-битова / 62 на 64-битова архитектура съдържат директно стойността на числото.

    Именно затова всяко x с клас Fixnum x.object_id == 2 * x + 1

    По подобен начин се интернират true, false, nil и символите. За сравнение, при обикновените обекти, VALUE се използва като адрес на структура с полета, методи и т.н. Пример:

    struct RClass {
        struct RBasic basic;
        VALUE super;
        rb_classext_t *ptr;
        struct method_table_wrapper *m_tbl_wrapper;
    };
    
  4. Петър, примерът показва, че определящото е първата буква.

    Не за всички константи важи стиловото правило, че трябва да са с главни букви. Както ще разберете малко по-натам, имената на класовете също са константи, но не се пишат изцяло с главни букви. :)
    За конкретният пример - да, според конвенцията тази константа трябва да е с главни букви, но за да е по-ясен примерът само първата е главна.

Трябва да сте влезли в системата, за да може да отговаряте на теми.