Пета задача

  1. Имаш следната ситуация в хранилището:

    commit4 <- HEAD
       |
    commit3
       |
    commit2
       |
    commit1
    

    Изпълняваш checkout(commit2.hash) и хранилището ти се променя на:

    commit2 <- HEAD
       |
    commit1
    

    Изпълняваш нов commit (не забравяй, че трябва да си добавил/премахнал обект за целта) и хранилището вече е:

    commit5 <- HEAD
       |
    commit2 
       |
    commit1
    
  2. commit4 <- HEAD
       |
    commit3
       |
    commit2
       |
    commit1
    
    irb> checkout(commit2.hash) 
    
    commit2 <- HEAD
       |
    commit1
    

    Мога ли да чекаутна commit3 или commit4 от настоящия стейт или при чекаут на предишен къмит се губи хисторито след него?

    EDIT:

    Така като чета примерни тест, се очаква обекта върнат от repo.commit('Blah') да има result пропръти и то да е обект представляващ самия commit, както би го върнал head. Ако съм прав, от описанието commit в задачата не става ясно.

    EDIT 2:

    repo.head.result.objects връща масив от обекти, които не трябва да отговорят на нищо, нали?

    В repo.log, вописанието на формата на датата няма секудни, 2 абзаца по-долу, след примерни код има секунди. Кое от двете е?

    1. Ако до сега сме имали commit-нато нещо с име "asd" и обект "sss" и изпълним: add("asd","sss") това ще се смята ли за промяна?

    2. За резултата от head се казва, че трябва да отговаря на метода objects, който трябва да върне списък с всички комитнати обекти в най-актуалния им вид. Това означава ли, че в конкретния случай не ни интересуват имената на обектите а само стойностите им?

    3. За checkout се казва, че резултатът трябва да е commit-ът, към който сме се върнали. Въпроса е това същия обект, като в резултата за head ли е или трябва да върнем нещо друго?

    1. Да, ще можеш да го commit-неш. Не се прави никакъв equality check на обектите.

    2. Без имена, само обектите. Ако ползваме примера от 1., head.result.objects трябва да върне ["sss"].

    3. Същия обект от гледна точка на операции, които ще извършваш върху него.

    1. Да, ако не е текущия branch.
    2. Тези промени не са афектирани от създаването на branch. Ако не са commit-нати все още никой branch "не знае" за тях. Ако направиш нов branch, преминеш към него и след това commit-неш, то промените ще бъдат направени само върху този новосъздаден branch.
  3. Имам проблем със instance_eval до колкото разбрах от лекцията докато съм в instance_eval аз мога динамично да си променям инстанцията на класа тоест ако по принцип self ми е object, то ако съм в class_name.instance_eval self се променя на текущия клас и аз мога да викам дадени методи без явен получател.Следователно както е дадено в примера аз извиквам

    repo = ObjectStore.init do
      add("value", 21)            <---- блока на функцията init
      commit("message")
    end
    

    където функцията init e

    [REDACTED]
    

    Извиква се конструктуктура на ObjectStore следователно ако е подаден блок според мен той трябва да се изпълни с не явен получтел в случея променливата repo, обаче ми дава грешка undefined method `add' for main:Object тоест получателя на метода не е ObjectStore, а Object защо се случва това и ако има нещо съществено което не съм разбрал ако може някой да ми обясни ?

  4. Трябва да оцениш - eval-неш блока, а не да имаш yield. Когато ползваш instance_eval, оценяваш някакъв блок в друг контекст. Но ти в случая подаваш с yield някакъв self, който е repo-то, на блока (даваш го на блока), ама не променяш self-а на блока.

  5. @Николай, погледни това (въпреки, че е за стара версия на Руби): http://ruby-doc.org/core-1.9.3/BasicObject.html#method-i-instance_eval

    Трудно ми е да ти дам насока, без да ти дам решението, но все пак. Какво правиш с блока, който е даден на функцията ти? Помедитирай над следното, използвайки прочетеното в линка:

    class Slon
    
       def self.set_up(&block)
         # what would you do to get it working?
       end
       ...
    end
    
    slon = Slon.set_up do
      feed(bananas)
      go_to_bed(Time.now)
    end
    

    Погледни и това: http://rubylearning.com/blog/2010/11/30/how-do-i-build-dsls-with-yield-and-instance_eval/ Доста приятна статия - последната секция преди wrap up-a те интересува.

    Също, показал си части от решението си, което няма да се хареса на екипа - помисли да го редактираш.

  6. Благодаря, направих го, искам да попитам при каквато и да е операция връщам обект, който отговаря на message, success?, error? и result(ако има такъв), в тестовете които са дадени обаче

    expect(repo.commit("So cool!")).to be_success("So cool!\n\t2 objects changed", repo.head.result)

    никъде не пише в условието че трябва да връщам и heada при commit

    Какво точно трябва да се върне?

  7. Това го питах малко по-горе в темата и @Станислав отговори (третото мнение на тази страница, втория EDIT) - идеята е, че repo.commit връща резултат, със съответния месидж, статус за успех и result обект представляващ току що направения commit с описания интерфейс (наистина този result не е написан експлицитно в условието). Този примерен тест работи, защото repo.commit гeнерира нов къмит (последен), а head се очаква да върне последния генериран commit като result.

  8. Здравейте, ако имаме следното нещо

    repo = ObjectStore.init
    puts repo.add('foo1', :bar1).result

    Какво трябва да се изпринтира?

    • :bar1
    • някакъв обект, който има @name и @object полета, които съответно можем да ги достъпим

    Същата ситуация и когато имаме:

    repo.remove('foo1').result
    repo.get('foo1').result

    Тъй като при тестовете на @Владо,

    repo.add('foo1', :bar1).result
    връща :bar1, а в условието на задачата не ми става много ясно под "обект" какво се разбира - самото пропърти от add(name, object) или друг обект, който представя дадения "елемент(name, object)".
  9. Имам въпроси относно обектите върнати от операциите:

    1. Трябва ли да се запаметяват message обектите някъде, за да може да бъдат access-нати по-късно? За message-ите на всеки commit трябва, защото са нужни в история на комитите, но за останалите не съм сигурен.
    2. Имаме следната ситуация: Намираме се в бранч "a_branch". Правим операция remove("an_object"). При наличие на този обект в "a_branch" операцията е успешна. Все още не сме commit-нали и сменяме на друг бранч "another_branch". От това, което прочетох и разбрах по-горе във коментарите, операциите се запазват, тоест сега ако commit-нем съответните промени ще се извършат върху "another_branch". Какво трябва да стане , ако "another_branch" обаче не съдържа "an_object"? Благодаря !
  10. И аз имам няколко въпроса: 1. Когато имаме неуспешен commit, примерно commit("baba"), мога ли да направя този commit head или просто изчезва 2. Когато съм "commitnal" обекти "baba" и "dqdo" и някав момент премахна тези обекти, този commit изчезва ли? 3.Този SHA1 по някав специален начин ли се вика или просто baba.hash 4.Мога ли да commitna два пъти с един и същ message, ако да какво става 5.И за изхода на log сякаш има още два \n,\n накрая или бъркам

  11. @Георги,

    1. Не съм сигурен какво имаш предвид под "message обекти". Ако имаш предвид съобщенията на commit-ите, да, трябват ти, защото head връща обект, представляващ последния commit в текущия бранч и този обект трябва да има метод message, връщащ съобщението на commit-а. Като вземеш предвид, че с checkout може да се върнеш на произволен commit назад, реално ти трябва да пазиш всичко за всички commit-и до момента.
    2. Няма да има тестове, в които сменяме branch-а, без да сме commit-нали.

    @Марк,

    1. Ако методът commit ти върне грешка, реално не си направил commit и нищо не е променено.
    2. Не, commit-ът не изчезва. Той е част от историята на проекта и можем да се върнем до него с checkout(commit_hash).
    3. Не се ползва методът Object#hash, а криптографски SHA-1 хеш. Има библиотека за това в Ruby, може да я ползвате. "baba".hash ще ти върне Fixnum, което няма нищо общо с формата на хеша, за който ние говорим.
    4. Да, можеш, няма проблем, message-а не е уникален. Ако е в различна дата, commit-ите ще са си различни (а и вероятно ще трябва да носят различни промени вътре). Не се грижи за уникалност на commit съобщенията.
    5. Не, няма нови редове в края. Само между отделните commit-и.
  12. @Георги

    1. Има checkout на commit, т.е. да
    2. Ако искаш го направи като git, т.е. премахни нещата за триене ако ги намя в другия бранч. (Няма да тестваме, че нещата са изтрити от commit-та.)

    @Марк

    1. Ако става дума за празни commit-и - може да се правят. Тоест става head.
    2. Не изчезва.
    3. Не трябва да ползваш Object#hash. Трябва ти криптографски SHA-1 хеш.
    4. Ще имаш 2 commit-а.
    5. Няма. :)

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