В тестовете има ли групиране на филтри в скоби? Защото
Filter1 & (Filter2 | Filter3)
е различно от
Filter1 & Filter2 | Filter3
.
В тестовете има ли групиране на филтри в скоби? Защото
Filter1 & (Filter2 | Filter3)
е различно от
Filter1 & Filter2 | Filter3
.
Съобразяваме се с приоритета на операторите. :)
Не, функцията [] просто трябва да получи един параметър - филтър. Но понеже филтъра има методи | и &, които получават филтър за параметър и връщат филтър, се получава възможност за такова "навързване" - Filter1 & Filter2 | Filter3. Ако имаше скоби, това щеше да е допълнителен метод може би и доста допълнително логика, за които със сигурност щеше да е споменато изрично.
Едит : моля да ме поправите ако греша :)
@Наско,
Скобите са просто механизъм за променяне на приоритета на извикване. По подразбиране &
е с по-висок приоритет от |
. Тоест, ако имаш A & B | C
, това е еквивалентно на D | C
, където D = A & B
. Ако сложим скоби така A & (B | C)
, тогава резултатът е A & E
, където E = B | C
. Не знам, дали стана много ясно, но идеята е че можеш да избереш в какъв ред да се изпълнят операциите. Това, че и двете операции приемат филтър и връщат филтър ги прави напълно използваеми в такъв вид групиране.
При @numbers[A & (B | C)]
стъпките за изпълнение са:
B
викаме метода |
, подавайки му филтъра C
. Резултат от изпълнението е филтър D
. Изразът се свежда до A & D
.A
викаме метода &
, подавайки му филтъра D
. Резултат от изпълнението е филтър E
.@numbers
с филтър E
.Тоест групирането със скоби ти идва напълно безплатно, щом си имплементирал оператора правилно.
Нещо такова.
Даа изясни ми се много повече. То всъщност и да не са предефинирани изразите не трябва допълнителна логика, можем да сложим скоби на този израз например:
"A.and(B).or(C)"
И да се получи:
"A.and((B).or(C))"
което също е напълно валидно, но с друг смисъл.
Тоест разликата реално между A.or(B).and(C) и "A | B & C" е в приоритета. Преди не знаех, че като предефинираме операторите всъщност приоритетът на изпълнение вече не е задължително от ляво надясно.
Благодаря :)
Възможно ли е да опишете точната последователност при извикване на филтрите тук:
@numbers[A | B & C]
Ясно е как ще се изпълнят (B & C = D и после A | D), но нали първо интерпретаторът (или както се води при Руби) вижда филтър А и негов метод | (логическо "или") с аргумент B. Просто го подминава и после стига до B & C = D и получаваме А | D?
Извинявам се, ако е прекалено, но все още не ми е ясно дали се тръгва по някакъв път първоначално, който се оказва грешен, за да се стигне до финалния вариант, където в крайна сметка се изпълнява всичко според приоритетността на операторите and/ or. Сиреч, "зад завесите" какво става?
@Любомир, Ruby изпълнява израза така, както Станислав го е написал по-горе:
B.&(C)
. Това продуцира резултат, да го наречем D
.A.|(D)
. Резултатът да наречем E
.@numbers.[](E)
.Това е. Не се тръгва по грешен път. Представи си, че кодът е parse-нат и поставен в AST, където листата са отделните компоненти на израза. Нищо не се изпълнява преди да му е дошъл редът. Ruby обхожда дървото и изчислява резултата според приоритета на операциите. Постепенно се стига до корена на дървото и там вече имаме резултат.
Трябва да сте влезли в системата, за да може да отговаряте на теми.