Втора задача

  1. Не, функцията [] просто трябва да получи един параметър - филтър. Но понеже филтъра има методи | и &, които получават филтър за параметър и връщат филтър, се получава възможност за такова "навързване" - Filter1 & Filter2 | Filter3. Ако имаше скоби, това щеше да е допълнителен метод може би и доста допълнително логика, за които със сигурност щеше да е споменато изрично.

    Едит : моля да ме поправите ако греша :)

  2. @Наско,

    Скобите са просто механизъм за променяне на приоритета на извикване. По подразбиране & е с по-висок приоритет от |. Тоест, ако имаш A & B | C, това е еквивалентно на D | C, където D = A & B. Ако сложим скоби така A & (B | C), тогава резултатът е A & E, където E = B | C. Не знам, дали стана много ясно, но идеята е че можеш да избереш в какъв ред да се изпълнят операциите. Това, че и двете операции приемат филтър и връщат филтър ги прави напълно използваеми в такъв вид групиране.

    При @numbers[A & (B | C)] стъпките за изпълнение са:

    1. На филтъра B викаме метода |, подавайки му филтъра C. Резултат от изпълнението е филтър D. Изразът се свежда до A & D.
    2. На филтъра A викаме метода &, подавайки му филтъра D. Резултат от изпълнението е филтър E.
    3. Филтрираме колекцията @numbers с филтър E.

    Тоест групирането със скоби ти идва напълно безплатно, щом си имплементирал оператора правилно.

    Нещо такова.

  3. Даа изясни ми се много повече. То всъщност и да не са предефинирани изразите не трябва допълнителна логика, можем да сложим скоби на този израз например:

    "A.and(B).or(C)" 
    

    И да се получи:

    "A.and((B).or(C))" 
    

    което също е напълно валидно, но с друг смисъл.

    Тоест разликата реално между A.or(B).and(C) и "A | B & C" е в приоритета. Преди не знаех, че като предефинираме операторите всъщност приоритетът на изпълнение вече не е задължително от ляво надясно.

    Благодаря :)

  4. Възможно ли е да опишете точната последователност при извикване на филтрите тук:

    @numbers[A | B & C]

    Ясно е как ще се изпълнят (B & C = D и после A | D), но нали първо интерпретаторът (или както се води при Руби) вижда филтър А и негов метод | (логическо "или") с аргумент B. Просто го подминава и после стига до B & C = D и получаваме А | D?

    Извинявам се, ако е прекалено, но все още не ми е ясно дали се тръгва по някакъв път първоначално, който се оказва грешен, за да се стигне до финалния вариант, където в крайна сметка се изпълнява всичко според приоритетността на операторите and/ or. Сиреч, "зад завесите" какво става?

  5. @Любомир, Ruby изпълнява израза така, както Станислав го е написал по-горе:

    1. Първо се изпълнява B.&(C). Това продуцира резултат, да го наречем D.
    2. Изпълнява се A.|(D). Резултатът да наречем E.
    3. Изпълнява се @numbers.[](E).

    Това е. Не се тръгва по грешен път. Представи си, че кодът е parse-нат и поставен в AST, където листата са отделните компоненти на израза. Нищо не се изпълнява преди да му е дошъл редът. Ruby обхожда дървото и изчислява резултата според приоритета на операциите. Постепенно се стига до корена на дървото и там вече имаме резултат.

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