Дайте доступ!

У меня всегда была мечта – писать программы под какую нить систему. И вот моя мечта сбылась… сегодня я провел почти весь день в попытке написать маленькую такую программульку под Мак ОС Х. Скажу сразу что успехом это мероприятие пока не увенчалось. Расскажу чуть о деталях: я хочу написать маленькую утилитку под Мак, так как для винды я её видел, а для Мака нет. Кроме того что под мак её нету, я сам бы хотел её пользоваться! Так вот, часть программы я уже написал, думаю процентов так 25, но основная фишка на чем я запоролся пару дней назад состояла в том что мне нужно писать файлики в /etc директорию и вот тут я застрял. Фишка в том что мне нужен админовский доступ что бы писать в /etc файлы, а как его получить я не знаю.

Я прочитал Апполовскую документацию и до сих пор не понимаю как оно должно работать. Некоторые вещи о которых пишут на форумах использовать нельзя, так как во-первых эта часть кода будет убрана в Mac OS 10.7, а во-вторых как рассказали в одном из видео с WWDC ( World Wide Development Conference ) оно не безопасно ( видимо из-за этого и удаляют ).

Решений на сколько я понял есть вcего несколько, одно это сделать демон и он будет выполнять эту важную операцию, второе сделать программу которая будет выполняться под root привилегиями и было ещё что-то но я не помню. Так вот я посмотрел на код всего того что есть и мне стало как-то не по себе… страницы кода ради того что бы исполнить одну операцию… Я все не как не могу прийти в себя, так как мне просто не понятно – зачем писать столько кода для авторизации одной операции? Я от части понимаю что это все сделано что бы сделать систему безопасной, но какой кошмар. Наверное это у меня шок из-за того что я не знаком с операционными системами и как оно там все вариться, но все же.

Думаю я продолжу поиски решений и надеюсь что нить найду.
Если у кого есть мысли то пишите и если есть желание то помогите… ох тяжелая эта работа из болота одному тащить бегемота.

Чирз!

Интересная логическая ошибка

Вчера увидел интересную ошибку или даже баг в коде и меня это побудило на то что бы написать немного об этом.

История:

Мы пишем много кода на Груви ( Groovy ) и как это бывает в любом языке по ходу написания допускаешь ошибки. На этот раз мы откопали ошибку в коде, которая была там походу долгое время, но не кто особо не обращал внимания, так как ошибка походу себя не проявляла да и была логическая, связанная с Груви. Для того что бы объяснить и показать что я имею ввиду, думаю приведу контраст между Груви и Жавой ( Java ).

Прелюдие:

Думаю все кто пишут на груви любят то что можно “изъясниться” кратко, в особенности по сравнению с жавой. Например посмотрим на класса “человек” написанный на жаве:

/** Java Code */
public class Person {
private String firstName;
private String lastName;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

}

А теперь посмотрим на тот же класс написанный на друви:

/** Groovy Code */
class Person {
String firstName
String lastName
}

Думаю что не заметить разницы просто не возможно. Говорят что “краткость сестра таланта”, но в случае груви это приходит с определенной ценой.

Ошибка:

Я не буду в даваться в подробности груви, а сразу прыгну к проблеме. Груви динамический язык и это приносит много приятностей, но так же и требований. Вот пример бага который мы нашли в коде:

def list = [“Hello”, null, 2, false, “End”, “”, 0, “Me?”, true, 100]
def flist = []
def elist = []
list.each {
if(it) {
flist << it } else { elist << it } } println "flist:" flist.each { println "$it" } println "\nelist:" elist.each { println "$it" }

Логика данного кода такова:
У нас есть лист вещей, и мы его сортируем по критерии: “если вещь что-то из себя представляет, то есть не пуста то суем это в flist, если нет то в elist.

Вывод будет:

flist:
Hello
2
End
Me?
true
100

elist:
null
false

0

Что не верно, так как мы хотим получить все данные которые из себя что-то представляют. То есть “false” – это тоже даные как и ноль “0”, но вполне логично эти два значения попали в лист elist. В итоге тут логическая ошибка, так как false и 0 должны попасть в flist, а все происходит из-за динамичности и краткости груви. То есть груви на лету присваивает объекту определенный класс типо String или Integer и в соответствии с этим делает вывод при запросе в “if(it)”. То есть если у нас есть “Hello” то при эвалюации if(“Hello”) если значение “Hello” ( то есть String переменной ) не пустое ( “Hello” ) то мы получим ответ true, а если пустое ( “” ) то получим false. Но тот же самый код будет не верно определять если объект будет номером или буленом ( boolean ). То есть если мы спросим if(0) то тут же получим false, – а это противоположная реакция примеру с текстом. Но если мы спросим if(1) то получим true – то есть все что кроме 0 это правда ( true ), а если 0 то ответом будет не правда ( false ). Думаю не буду разбирать пример с буленом так как тут и так все понятно.

Починить этот баг очень просто, заменив всего одну линию:

if(it != null && it != “”)

Ответ на этот раз будет:

flist:
Hello
2
false
End
0
Me?
true
100

elist:
null

Если в этот пример хорошенько вдуматься то можно увидеть своего рода прикольную ошибку. Меня она лично порадовала, так как код будет работать правильно в большинстве случаев, но при этом код кривой. Жава а этот счет более адекватна, так как она не позволит сделать if(tmp) – так как она не динамична как груви, но и писать нужно будет больше кода. Вот пример примерно того же только на Жаве:

Vector list = new Vector();
Vector flist = new Vector();
Vector elist = new Vector();

list.add(“Hello”);
list.add(null);
list.add(2);
list.add(false);
list.add(“End”);
list.add(“”);
list.add(0);
list.add(“Me?”);
list.add(true);
list.add(100);

for (Iterator it = list.iterator(); it.hasNext();) {
Object o = it.next();
if(o instanceof java.lang.String) {
if(o != “”) flist.add(o);
else elist.add(o);
}
if(o instanceof java.lang.Integer) {
flist.add(o);
}
if(o == null) {
elist.add(o);
}
}
System.out.println(“flist:”);
for (Iterator it = flist.iterator(); it.hasNext();) {
System.out.println(it.next());
}
System.out.println(“\nelist:”);
for (Iterator it = elist.iterator(); it.hasNext();) {
System.out.println(it.next());
}

Кода больше, а по сути делает тоже самое. Хотя не совсем, этот код довольно лимитирован тем что может быть в листе, на данный момент только String, Integer и просто null. Но все же забавно!

Ладно у кого будут мысли пишите, а я спать.