Курник

  1. Ако случайно някой не знае значението на тази звучна българска думичка - мястото където живеят кокошките и петелЯ. :hatched_chick:

    Та идеята ми е тук да си цъкаме някакви, неща, които или са офтопик или са прекалено малки за цяла отделна тема - като всеки уважаващ себе си форум, разбира се. :smile:

    Какво предизвика тази тема? Статия, на която попаднах в твитер, тематично свързана с последната лекция. :smile:

  2. Само да вметна че българската думичка е "кокошарник". Курник идва от Русия, където думата за кокошка е "курица". Иначе думата "курник" все още се ползва в някои диалекти, както и в по-архаични текстове. Предполагам всеки помни поне една приказка в която "Кума Лиса влезе в курника да си открадне кокошчица". Да не се бърка с "накурник", която е българската дума за "презерватив". Ползва се рядко в ежедневието(думата де). Произходът ѝ е същият какъвто и на "намордник" - нещо което се слага на мордата. ("Морда" - предната част от главата при гръбначните животни). Източник: wikipedia.

  3. Какво научих покрай проекта.

    Понеже вече няколко съботи и недели си пиша проекта, а и понеже ми хареса идеята на 5тото домашно, реших да споделя какво съм научил покрай проекта. И по-скоро искам да споделя не колко съм бил тъп преди и колко умен сега, ами да разкажа за някои неща в които си счупих главата и (евентуално) опитът ми да бъде полезен на някоя заблудена душа от курса.

    Първо, data_mapper. Реших да ползвам датамапер вместо активрекорд, защото някъде (вече напомня къде) прочетох че е по-лесно за noob-ове като мен. Правилен или не, изборът ми е вече факт и всичко работи идеално. Какво обаче ми създаде ядове докато го подкарам?

    1. Зависимостите. В никой пример който гледах не успях да намеря списък с всички джемове дето ми трябват. В крайна сметка така и не разбрах кои са необходими и кои не. Мога да постна списък с джемовете, които съм инсталирал, но сред тях ще има и някои излишни. Оправих се чрез Google-ване на конкретните съобщения за грешки.
    2. Set-ърите на обектите. Оказа се че когато напишете

       property :foo, String
      

      се създава сетър и гетър за обекта. Освен поведението, което се очаква да имат, те правят и нещо скрито, което има отношение към заявките в базата. Какъв беше проблемът при мен? Имам клас Период с 2 property-та - от и до. За да поддържам консистентността на обектите, правя валидации в сетърите. И съответно в тях не извиквах супера. Защо - ами защото класът го бях написал преди 2-3 седмици, когато проектът ми не ползваше бази данни (бях още на начално ниво) и съответно супер нямаше. Доста време ми отне да съобразя защо всяка заявка save до базата беше "INSERT INTO "periods" DEFAULT VALUES"

    3. Някои методи. Датамапера дефинира някои класови методи, сред които методът load, който ми трябваше в един друг клас. Това поне се съобразява лесно.

    Тестове. Не знам защо го подкарах мързеливата, но реших да не чета за някакъв framework за тестване, а да ползвам примера от лекциите, като го доразвия малко. Ето какво ползвам в момента:

    require 'data_mapper'
    
    #require all models
    
    Dir["./src/model/*.rb"].each { |file| require file}
    
    DataMapper::Logger.new $stdout, :debug
    DataMapper.setup :default, "sqlite:db/test.db"
    DataMapper.finalize
    DataMapper.auto_migrate!
    #DataMapper.auto_upgrade!
    
    
    class Test
      def Test.ok(expected, actual, string = nil)
        success = (expected == actual)
        if success then
          puts "\033[42mok\033[0m"#Green -> ok -> White again
          return
        else
          puts "\033[41mfailed"#Red
          puts string if string
          puts "Expected #{expected.inspect}, Actual #{actual.inspect}"
          puts caller.join "\n"
          puts "\033[0m"#Back to white
        end
      end
    end
    

    Настройвам тестова база, защото планирам да тествам и четене/писане в базата.

    Тестовете ги пускам с watchr. Хубаво, ама трябва като напиша нов тест (в нов файл), трябва да променям файла watchr.rb. Пък мен не ме кефи. Затова съм си написал следният скрипт

    run_all_tests.sh:

    ls ./tests/*_test.rb |cat| while read file
    do
      echo "$file"
      ruby $file
    done
    

    Конвенцията ми е че всички тестове са в папка test и завършват на _test.rb. Това май не е добра конвенция и скоро ще рефактурирам, но това няма съществено да промени скрипта.

    Това добре, но когато създам нов файл трябва да го добавям в watchr.rb. Това в един момент също става досадно. Затова пък си написах следния скрипт

    create_watchr.sh:

    watchr="watchr.rb"
    
    echo "">$watchr
    find|cat|grep .rb| while read file
    do
      #Remove leading "./"
      file=`echo "$file"|sed -r 's/^.{2}//'`
    
      echo "watch(\"$file\") do">>$watchr
      echo "  system \"clear\"">>$watchr
      echo "  system \"./tests/run_all_tests.sh\"">>$watchr
      echo "end">>$watchr
      echo "">>$watchr
    done
    

    Този скрипт генерира следният файл watchr.rb:

    watch("watchr.rb.bak") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("tests/period_test.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("tests/test.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("tests/statistic_test.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("watchr.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("src/model/period.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("src/model/statistic.rb") do
     system "clear"
     system "./tests/run_all_tests.sh"
    end
    
    watch("src/model/.statistic.rb.swp") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("src/util/device_manager.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("src/util/ticker.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    
    watch("main.rb") do
      system "clear"
      system "./tests/run_all_tests.sh"
    end
    

    Тук е моментът да кажа "Да, Кънев, има 2 излишни празни реда в началото и в края" и "Да, Кънев, грозно е". Тъй като мързелът не е добродетел, обещавам да намеря време и да оправя скрипта да не генерира грозен код.

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

  4. @Валентин, супер идея да споделиш неща така. Може би си заслужава да помислим и за нещо повече от форумите (например раздел "Статии"), където такива по-полезни публикации да намират подобаващо място.

    А относно това, което си направил с watchr — не можеше ли просто да му подадеш регулярен израз, с който му казваш какво искаш да следиш? Според документацията му, може. Примерно, нещо такова:

    watch('.*\.rb(\.swp)?') do
      system "clear && ./tests/run_all_tests.sh"
    end
    
  5. @Вальо, (1) по какъв начин това е въпрос за тази тема и (2) въпроса ти е мега неясен. Искаш нещо като (1) before_filter, ама в Rails, (2) нещо в Rails, което е подобно, ама друго или (3) нещо като before_filter извън Rails? И най-вече за какво ти е?

    Бъди добър интернетаджия и пусни това в нова тема.

  6. @Валентин, Webrick има едно-единствено преимущество и то е, че е мъничък, прост и тръгва без конфигурация. Това го прави перфектен за пробване на уеб фреймуърк и донякъде за разработка. Във всички останали случаи е по-добре да се ползва друг сървър — било то Thin, Puma, Unicorn, (Standalone) Passenger или нещо друго. За всяка форма на production употреба на уеб проект е задължително да се замени Webrick с нещо друго, а не да се "оправя" бавнотата му.

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