Pull to refresh

Comments 105

> Ruby был задуман в 1993-м году японцем Юкихиро Мацумото, стремившимся создать язык, вобравший из других языков самые лучше подходы, облегчающие труд программиста.

HTML version timeline
November 24, 1995
HTML 2.0 was published as IETF RFC 1866.
Тут дело вкуса, конечно, но языки со статической типизацией нравятся мне намного больше. В основном, из-за боле жесткого «каркаса» кода, как бы сказать. В языках типа Ruby или PHP никогда не знаешь, когда подорвешся на ошибке, вызванной неправильным написанием функции или переменной. Конечно, написание тестов лечит, но в компилируемых языках таких ошибок все равно на порядки меньше. Соответственно, прогонов тестов и их исправление меньше тоже. И за счет большей информации о структуре кода refactoring его значительно проще. И сопровождение легче. И вообще… :)
Это как раз не минус а плюс языку. Тот же .net с каждым релизом становится все более лояльнее к динамической типизации (var, dynamic).
Тут дело не вкуса а опыта. У меня, например, вообще не возникает никаких проблем вызванных неправильным написанием функции или переменной. Я просто проверяю перед тем как коммитить ;)
var — это скорее синтаксис. dynamic — да, нечто вроде variant.

> Тут дело не вкуса а опыта. У меня, например, вообще не возникает никаких проблем вызванных неправильным написанием функции или переменной. Я просто проверяю перед тем как коммитить ;)

Согласен, с опытом придет понимание, что статика лучше :-P Потому что проверять перед коммитом надо меньше :)
Я как раз наоборот с senior .net developer-а на php перешел, так что могу со всей ответственностью заявить, что динамика таки удобнее для меня ;)

> Потому что проверять перед коммитом надо меньше
Ну вы же не с закрытыми глазами коммитете, все равно проверяете ;)
> Я как раз наоборот с senior .net developer-а на php перешел, так что могу со всей ответственностью заявить, что динамика таки удобнее для меня ;)

Дело вкуса. :)

>> Потому что проверять перед коммитом надо меньше
>Ну вы же не с закрытыми глазами коммитете, все равно проверяете ;)
Ну да. Проверяю. Но не все покрыто тестами. Плюс все тесты прогнать — это около 2-х часов времени. Слишком высока цена оишкби. Да.
Я тоже, в бытность дотнетчика, на себе тельняшку рвал и доказывал своему другу (php-ку), что строгая типизация это наше все, и что с ней жить проще, удобней и спокойней.

Но если бы у вас был опыт в обоих сверах, и в .net и в php, то вы могли бы объективно сравнивать динамическую со статической типизацией. А так как у вас опыт только в дотнете то ваше мнение субъективно ;)
Та я вообще-то ZCE. С опытом программирования на PHP около 7 лет. Да и сейчас на нем пишу. Так что не извиняйте…
Кстати, опыт программирования на .NET около 4-x лет.
Учили в школе по физике, что нельзя получить выигрыш в работе (A = F·s)? Можно лишь в силе или в расстоянии. Вот здесь то же самое. С одной стороны плюс, с другой минус… Это как посмотреть.
А вы в школе учили что можно выиграть в производительности или в кпд?
Учил. Как говорится… и чё?
C# является только статически типизированным языком. dynamic — опирается на возможности самой CLR 4 (путем своего рода интроспекции). при компиляции переменной объявляется тип object.
Понятно, какие тогда есть по-твоему альтернативы? Java + Spring/Tapestry/JSF?
Не знаю, вот интересный обзор по теме: , сейчас вчитаюсь.
Не силен в Java. Пока ушел в стек MS. Не жалею. Но под Web пишу мало, только для интранета на ASP.MVC немного.
UFO just landed and posted this here
Десктоп, в основном. Даже не GUI, а, скорее, логику. Ну и всякими разными вопросами занимаюсь. Вот сегодня копался в .NET interop — CCW, RCW, WinDBG и все в таком-же духе.
это в честь выхода 1.9.3? неплохо было бы пару слов про него, а так спасибо, интересно
Нет, просто так случайно получилось, что эти два события совпали :)) Я пока не так хорошо разбираюсь в Ruby, чтобы писать что-то про особенности 1.9.3, тем более что судя по описанию, там нет особых «революционных» изменений. Зато выход новой версии подтвреждает тот факт, что язык жив и развивается ;)
Руби клевый. В нем есть блоки и он хорошо заточен для создания eDSL. Я в целом по работе использую python (по ряду причин), а для себя ruby (потому что нравится) — за последние несколько лет их довольно хорошо сравнил. Ruby в целом производит благоприятное впечатление — лучше работает с вызовом shell (короче синтаксис, корректно обрабатывает пробелы), лучше интерполирует строки (при интерполяции можно вставлять произвольный код), DSL опять же. Но библиотек в комплекте поменьше и менее распространен как default scripting language (например, скачивая VirtualBox можно ожидать готовых биндингов для python).
Предлагаю для заинтересовавшихся закинуть в комментах список хороших книжек по последним версиям Ruby/RoR.
Я как раз такой заинтересовавшийся :)
Флэнаган Д., Мацумото Ю… Язык программирования Ruby (http://elbooka.com/raznaja-literatura/kniga-uchebnik/10648-flenagan-d-macumoto-yu-yazyk-programmirovaniya-ruby.html) — полагаю, эта вещь обязательна для прочтения :)
Yehuda Katz, Ryan Bigg. Rails 3 in Action (http://mirknig.com/knigi/programming/1181441404-rails-3-in-action.html) — пусть и на английском, но зато от основателя :)
> пусть и на английском,

ИМХО, для материалов про Ruby это не должно быть минусом. Когда искал, заметил что всякого на русском гораздо меньше чем на английском. Понятно, что так будет для любого языка, но все же тут совсем мало. Я б не стал на него смотреть, если бы не знал хоть как-нибудь английский. Или японский :)
Естественно, просто одно дело изучение нового языка, а другое — углубление в нём. Для того, чтобы начать, хочется чего-то простого и понятного, а не разбираться ещё к тому же с языком. Другой вопрос что те книги, что есть у нас переведённые, иногда ОЧЕНЬ сильно отстают по времени — переведено какое-нибудь 2nd Edition за 2009-й, а не переведённое 4th Edition — от 2011-го. А если за это время успел выйти Rails 3, к примеру — то это всё очень сильно меняет ;)
Sam Ruby — Agile web development with rails (http://www.torrents.net/torrent/1931845/Agile-Web-Development-with-Rails-4e-%28Rails-3.1%29---Ruby,-Thomas,-Hansson---Pragmatic-%282011%29.epub/) — тоже весьма полезная книга, насколько я могу судить.
Programming Ruby 1.9: The Pragmatic Programmers' Guide (http://rutracker.org/forum/viewtopic.php?t=3768727) — и ещё одна книга, на последок. Думаю, этих четырёх вполне хватит для начала ;)
Мне кажется, что стоит начать с этого — mislav.uniqpath.com/poignant-guide/
Перевод книг по руби на русском (которые видел я) просто отвратителен.
Я пишу на С++ (который очень люблю), изучаю и понемногу пишу на Haskell (который люблю не меньше, но понимаю пока похуже:)). Моё знакомство с Ruby состоялось полмесяца назад при помощи книги «Seven Languages in Seven Weeks». Так вот первое впечатление: язык реально создан для понимания программистами, а не компьютерами. Хороший код на Ruby читается практически так же легко, как текст на английском. Мне очень понравилось.
Расскажите почему любите С++. А то мне тут в блог понабросали комментариев что С++ типа отстой и должен умереть и все такое…
Потому что он сложный (и тем не менее я его знаю), мощный, позволяет контролировать всё на низком уровне, но при этом не заставляет, программы на нём работают быстро.
Ваше сообщение ну как-будто про ассемблер написано.
Хотите сказать, что С++ — простой язык? ))
Очень нравится Руби, но вот производительность до сих пор отталкивает :(
Интересно, а поподробнее можно? С чем сравнивали, на каких проектах?
Сравнивал с тем, что знаю — пхп)) Не на проектах, простые синтетические тесты (знаю что они не очень то показательны) по типу перебора массива в несколько сотен тысяч элементов и прочее. В добавок сколько не читал про руби, в том числе и здесь, на хабре, все время натыкался на утверждение что руби скорее удобен чем производителен (в разных вариациях, но схожих по смыслу). Честно, буду очень рад увидеть воочию опровержение всего выше сказанного :)
Возьмите реальный тест и убедитесь :)

В мире .NET тот же NHibernate, в сравнении с прямым доступом к БД, тоже тормозит на загрузке 1000 объектов. Причем (по моим тестам) на порядок, минимум раз в 10, а то и в 50. В пятьдесят. Медленнее. 50 мс заместо 1 мс. Зато экономит много часов разработки :)
Понятно, на тестах он уже не сильно уступает, да и со времени 1.8 Ruby успел немного реабилитироваться, а в последней версии 1.9.3 скорости уделено довольно большое внимание (http://linux.org.by/blog/1626/ruby-1-9-3/)
А вам не приходило в голову что время программиста намного дороже чем железяки?
Ответил чуть ниже :)
В веб-приложениях язык почти никогда не лимитирует производительность. На неграмотно составленном запросе теряешь гораздо больше. Если где-то получаются тормоза из-за самого Ruby, значит вы делаете это неправильно (или, как вариант, уже есть C-шное расширение для этой цели).
Петя, и это опять не так.

Рельсы реально тормозят. Очень неприятно. Сложное приложение тратит по 500 мс на рендеринг шаблонов. Причем, тормоза такие: убираем везде блоки вида content_tag do end и в два раза ускоряем приложение.

500 мс на просто перекладывание данных в памяти — это чудовищное время.

Ruby 1.9 тут ничуть не быстрее 1.8. Ровно те же результаты в рамках 40%-ной погрешности.

Вопрос в том, что такие жуткие тормоза можно простить за те удобства, которые дают рельсы.
Тормозят и хер бы с ними.
Я потому и написал «почти». Про тормоза с шаблонами (правда, я натыкался на них с большими уровнями вложенности) я знаю.
По 1.9 vs 1.8 ваше мнение понятно. Вам — верю :) А вот по поводу рельс. Все эти печальные факты про вторые рельсы или про тройку? Вроде как в третьей версии очень много сделали для оптимизации.
Я не заметил серьезного изменения в скорости работы при смене 1.8 на 1.9

Под серьезным изменением я подразумеваю не единицы процентов, намерянные на синтетических тестах, а общее ускорение системы хотя бы в 2-4 раза.

Это я говорю про сайт среднего размера в котором используется порядка 40 паршиалов и темплейтов для генерации страницы.
Я не заметил серьезного изменения в скорости работы при смене 1.8 на 1.9

Эм, я спрашивал именно про разницу между RoR 2.x и 3.x

И если уже затронули тему интерпретаторов, а JRuby не пробовали в боевых условиях?
С 2 на 3 тоже разницы серьезной не заметно.

JRuby не пробовал, но я так понимаю, что и там никакой серьезной разницы нет.
к чертям синтетические тесты, это для тех, кто в форумах терплется, а не сайты делает.
В настоящее время производительность языка не так важна, как скорость разработки. Если, скажем, программист сможет справиться с заданием за месяц разработки на Ruby вместо двух, чем на более производительном языке, то покупка/аренда дополнительного оборудования(чтобы компенсировать медлительность языка) все равно будет дешевле, чем лишний месяц работы программиста.
Для меня важнее производительность, в данный момент, ибо сейчас я работаю над своим проектом, а не в компании т.к. учеба и основная работа присутствуют :)
Тем более вы должны ценить свое время :)
>использование удобного JavaScript-framework'а Prototype
в актуальной версии рельс 3.1 по-умолчанию используется jquery, ну и про удобство прототайпа в наше время говорить как-то не очень.
Такое ощущение, что автор не работал плотно с рельсой
Ну, если бы ты внимательно читал статью (5 абзац сверху), то заметил бы, что я пока подошёл к вопросу со стороны перспектив развития, а не нюансов языка. Я буду благодарен за любые стоящие дополнения, тем более что с JavaScript я работал немного. Может, подскажешь, что есть из более удобных инструментов для работы с ним?
не совсем. Jquery по-умолчанию в рельсе используется для реализации всяких вспомогательных штук, вроде remote => true. Backbone.js — это в другую сторону (кстати, для него есть gem backbone-rails).
Опять же в 3.1 добавили поддержку coffeescript и asset pipeline. С одной стороны, это круто. Лично мне писать на кофескрипте приятнее, чем на чистом JS. Asset pipeline — забавная штука, но пока с ней разберешься в продакшене — наматеришься. С другой стороны, все эти навороты добавляют лишних зависимостей к рельсе, что медленно и, иногда, глючно.

А про руби написано клево. Правда, можно было бы рассказать про Матза, какой он хороший-нехороший, что он всячески не хотел видеть руби для веба и тд и тп. Ну и что он работает сейчас в хероку :)

Еще можно упомянуть руби/рэйлз сообщество, вроде Аарона «Сосисочная вечеринка» Патерсена, Хосе Валима, разные пипкоды и рейлзкасты. Ну да статья ваша
Думаю, если я всё-таки свяжу свою дальнейшую жизни (ну, или хотя бы часть её :) с Ruby, то тогда уже смогу написать что-то более глубокое и интересное, а пока это так, общий обзор ;) Но всё равно благодарю за участие и пояснения, буду думать!
А что за история с «Сосисочная вечеринка»? Это ведь не перевод тендерлав'а?
он частенько в твиттере пишет про сосисочные вечеринки и про мясо
Руби клёвый. Мы свинтили на него с Erlang (!!) и пока не жалеем.
Значит вы просто выбрали эрланг для не его задачи, либо не вышли в продакшн.
Макс? :)

Эрланг стоял у истоков той экспертной системы, о которой я спрашивал в ror2ru. Он там был реально в тему, использовался ERESYE, exmpp, процессы-сообщения. Руби здесь реально на грани применимости, но простота разработки победила здравый смысл. Реально, не жалею!

P.S. Все в продакшне :)
Использую Ruby 1.8.7 в связке не с RoR, а Sinatra. Доволен как слон. Скорость работы благодаря отсутствию лишних компонентов и присутствию Rake и DSL меня вполне устраивает.

А что нравится еще больше — это огромная скорость разработки благодаря множеству плюшек языка.
Переходите на 1.9.3. Версии 1.8.7 (и всей ветке 1.8 вообще) уже больше двух лет, и не осталось ни одной причины ее использовать.
есть REE, который якобы кушает меньше памяти, но проигрывает в производительности 1.9.2 и 1.9.3.
Хотя, я его год уже не использую
Основной источник экономии памяти — патч, позволяющий ОС использовать copy-on-write при fork()-е — уже давно внедрен в 1.9.

В REE есть кое-какие крутилочки, отсутствующие в 1.9, но если вы не Твиттер, то вряд ли они вам нужны. А если и нужны, то они подключаются обратно одной строкой в консоли через rvm.
Петя, это не так. Во-первых, в 1.9 до сих пор УЖАСНЫЕ проблемы с кодировкой. И они останутся навсегда.

Во-вторых, не весь софт с экстеншнами переведен на 1.9

Собственно, нет ни одной причины _апгрейдиться_ до 1.9 Начинать новый проект — скрепя сердце можно, апгрейдить — нет смысла.
Да? И в чем же заключаются УЖАСНЫЕ проблемы? Вот 1.8 — это и правда одна большая проблема с кодировками, а точнее полным их отсутствием.

Экстеншны «портируются» на 1.9 путем однокнопочной замены RString(value)->x на RSTRING_x(value). Не вижу в этом проблемы.
Петя, от того что ты не видишь проблем, они не исчезают.

Портировано не всё, причем со словами «портировать и не будем, потому что 1.8 работает». И это правда.

В 1.8 проблем с кодировками не было в принципе. Всё было идеально. Просто идеально.

1.9 с его дебильно задизайненной недосистемой недокодировок (юникода ведь в 1.9 как не было, так и нет) привел к тому, что многие вещи поломались непредсказуемо. Например, у меня был код, пакующий объекты в эрланговые термы. Он разломался непредсказуемо, понавтыкались везде лишние байтики на полуволшебной трансформации юникода в ASCII и обратно.

Так что Петя, что касается того, что сломалось или нет и что было удобно или нет, то ты ещё просто зеленоват для этих суждений и у тебя явно маловато опыта собственно в рельсах.
Прежде чем переходить на личности, неплохо было бы, ну, для разнообразия, показать примеры неработающего кода и экстеншнов. Просто чтобы не выглядеть аггрессивным троллем, который не осилил 1.9.
Так ведь никто и не обещал полной обратной совместимости при переходе на 1.9, ведь правда?
И очень хотелось бы посмотреть на правильно и грамотно задизайненную систему кодировок.

P.S. У нас уже год работает сайт на 1.9, где люди пишут на ~20 разных языках помимо английского. Никаких ужасных проблем с кодировками мы так и не увидели.
Собственно да, я думаю чуть боле детальное описание проблем было бы очень полезным. Что называется «наступил на грабли сам, предупреди другого».
правильная и грамотно задизайненная система кодировок в 1.8

opaque байтовый массив без магических трансформаций и аксессоры для юникода.

99% людей, кричащих о юникодных строках даже близко не понимают масштаба проблем с юникодом. Ведь в нём нет букв. Вообще. Есть несколько слоёв разных абстракций, которые крайне сложны в обработке. А букв в юникоде нет. Все эти тонкости даже и не планировалось решать в ruby 1.9
>Петя, это не так. Во-первых, в 1.9 до сих пор УЖАСНЫЕ проблемы с кодировкой. И они останутся навсегда.

Указывать кодировку в каждом файле такая большая проблема?
Ратмир. Слова про «до версии 1.8 язык развивался, сохраняя совместимость с предыдущими версиями» — это ложь.

С появлением и развитием рельс Матцумото начал умышленно вносить патчи типа chars и length, умышленно ломающие рельсы, причем в минорных версиях (патчлевелах)
Но сейчас все немного поменялось, надеюсь. Он и на мобильные технологии, и на облака смотрит. Поправте если я не прав.
вроде как сообщали, что теперь Матц работает в heroku, и вроде бы как теперь можно надеяться на какие-то классные изменения, но лично я немного пессиместично настроен. А что творится в голове у Матца и как оно поменялось после трудоустройства — знает только он :)
Проблема в том, что он ненавидел рельсы. Это странное поведение, но может связано с фашизмом японцев.

Он никогда не общался ни с кем из рельс, никогда не проводил совместные встречи или чего-то подобного и не координировал выпуск версий руби с единственным практическим применением своего творения.

Более того: он вообще не считает, что рельсы — единственное благодаря чему мир узнал про руби. Наверное, это связано с конфликтом в голове, в которой с одной стороны мир заканчивается островом, а дальше живут варвары, а с другой стороны это совсем не так.

Короче, чужая душа потемки, гадать можно о причинах сколько угодно. Результат прост: Матц принципиально не признает Rails в качестве killer app для Ruby, но реально это понимает и это его нервирует.

Итоги простые: например выкатывают патч с методом Array#length, который _очень_ тонко ломает функциональность рельс. Я провозился почти день с дебаггером.

Или chars. Юлик Тарханов делает прекрасную поддержку юникода в рельсы, Матц выкатывает апдейт, который целенаправленно использует те же методы, которые использует Юлик и тонко ломает его.

Кодировки. Это просто нет цензурных слов. Всё работает. В 1.8 всё прекрасно и идеально работает. Ни у кого нет никаких проблем. Вообще. Матц выкатывает нечто, что требует уже больше полутора лет для адаптации. Полтора года возни с неработающей системой кодировок и всё ради того, что бы у белых варваров было побольше проблем с рельсами.

Очень надеюсь, что сотрудничество в Хероку исправит эту ситуацию.
Весьма интересные вещи ты пишешь, если дела обстаят действительно так, то мой прогноз нуждается в корректировке. Попробую последить, как сейчас развивается ситуация, может действительно всё более-менее пришло в норму. С Синатра, я надеюсь, он не враждует? :)
говорю же: чужая душа потемки.
Интересный топик получился… читаешь сам топик — хочется писать на Руби, читаешь последние комментарии — полностью отбивает желание писать на Руби :(
Ну на самом деле все не так плохо. erlyvideo описывает политические игры людей. Это не мешает ему успешно использовать рельсы, насколько я понимаю. Разные подковерные игры есть всегда, там где есть люид. Не стоит мешать это с конечно технологией.

Этак, надо отказаться от питона потому что гугль как то забил на unladen-swallow. Отказаться от JVM, потому что гладиолус оракл тот еще патентный тролль. PHP не использовать, потому что полезнейший функционал php-fpm долго не могли пропихнуть в апстрим. А от linux надо просто бежать, потому что там полный террариум в плане, какие патчи включать в ванильное ядро, а какие нет.

Рельсы весьма хороши, просто нужно понимать их нишу и ограничения.

Это все понятно, но когда создатель языка намеренно (?) ломает функционал инструментария — это как-то не комильфо все же. Если действительно такие косяки с кодировкой и UTF8 не поддерживается то я лучше подожду когда они там угомонятся :)
1) «Создается впечатление», а не «намеренно»
2) У руби код открыт, и матц — не единственный разработчик )))

Короче, не надо волноваться, белых варваров слишком много на одного гордого самурая, и кнопку форк еще никто не отменял.
это неверное понимание. Всё таки есть рельсы и их авторы делают огромный объём работы, что бы всё работало.

Чего не скажешь об авторе руби.
Даже читать смешно. matz такой нехороший, аж костыли в языке стал убирать, лишь бы dhh напакостить :D
Кстати, товарищи — на днях было офф заявление, что ветка 1.8.7 будет поддерживаться до 2012 года. Потом багфиксы уже не будут на нее выпускать.
Это плохая новость.
А хорошая — на днях вышел руби 1.9.3!

И я что-то не выкупил почему люди на ветке 1.9 плачут о кодировке — почти единственное отличие 1.8 и 1.9 как раз в введении НОРМАЛЬНОЙ поддержи разных кодировок. Епть.
Раньше нужно было побайтово что-то пересобирать, или кучу костылей городить, теперь же есть
#encoding:utf-8
Неужели это плохо?
А если нужно баловаться с регистром или вводом пользовательских данных — есть же гемы. Подключи и работай.
UFO just landed and posted this here
Принцип «наименьшей неожиданности»??? да вы шутите! А вы пробовали разделить 3 на 2?
получается 0. И что? Для строго типизированного языка, коим руби является, это вполне ожидаем результат. Для того что бы ожидать, чтото все же нужно знать исходные данные. В манах на руби это описано.
Вообще-то, 3/2 = 1… согласитесь — неожиданно? Тем более если ожидался 0, как вы утверждаете:)
Поймали, поймали :) Я второпях почему то поделил 2 на 3, и конечно получился 0. Но что 2 / 3 = 0, что 3 / 2 = 1 лично для меня вполне ожидаемо. int / int = int

Но это бессмысленный спор… Я вот могу ожидать, что руби мне будет кофе вариать. Беда ли это руби, что оно это не делает? Тут скорее вопрос бэкграунда. Для статической типизации вполне нормально. Кто работал до этого с ЯП со статической типизацией — тем привычно. Кто привык к динамической — конечно будет казаться странным. На вкус и цвет все фломастеры разные…
irb(main):001:0> 3/2
=> 1
irb(main):002:0> 3/2.to_f
=> 1.5
irb(main):003:0>

ЧЯДНТ?
(Ввиду моей кармы на Хабре, писать могу раз в час, так что звыняйте.)
А мне вот кажется странным это поведение :) Я бы скорее ожидал ошибку для (3/2.to_f) ибо делим int на float (2.to_f — я так понимаю это вещественное) :)
Вообще-то мы делим объект на объект.
В руби же все объекты, сколько можно.

Когда в школе сначала Вас учат, что есть только положительные цифры и ноль — вы понимаете и кайфуете.
Через 5 лет Вам покажут, что есть еще и отрицальные числа — это ппц. Их же не видно!
Еще через 3 года Вам скажут, что считать нужно не с 1, а с 0 — это разрыв мозга. Что И и ИЛИ — это не то, что Вы всю жизнь знали. Апогей апофеоза будет откровение, что «0», зерро который, не такой уже и полный ноль. Потому что есть nill или null.
Потом, в конце — покажут двоичную систему и хекс. Если попадется олдскульный препод — он еще и про советскую троичную раскажет. И тд. и тп…

Вам каждые пару лет ломают стереотипы.

Если Вам мозолит глаза синтаксис — вот:
irb(main):001:0> 3/2
=> 1
irb(main):002:0> 3/2.0
=> 1.5
irb(main):003:0>
Так ведь проще?

Пора бы уже привыкнуть ) Принимать, юзать и кайфовать ^-^
у "." более высокий приоритет чем у "/", поэтому 3/2.to_f нужно читать как 3/(2.to_f)
Спасибо, буду знать :)
Sign up to leave a comment.

Articles

Change theme settings