Sign in or register
You'll be able to write comments and posts, like content, and much more
Search
Dark theme

Posts by tag: IT

Терминология в PHP: нелепость за нелепостью

Пыха - это всегда что-то с чем-то. Как яркий пример, можно вспомнить бездумный порядок аргументов в функциях: array_slice() - тут массив первым аргументом, array_key_exists() - здесь массив вторым аргументом и т.п. Но я сейчас про термины. В программировании есть устоявшиеся термины.

Например, перегрузка функций! Это когда функция может принимать разное количество аргументов и/или разные типы аргументов:

// C++
int add(int a, int b) {
  return a + b;
}

double add(double a, double b) {
  return a + b;
}

А что в PHP? А в PHP перегрузка (overloading) - это по факту перехват обращений к несуществующим свойствам и методам через магические методы!

// PHP :)
class Magic {
    public function __call($name, $args) {
        return "дернули метод $name";
    }
    public function __get($name) {
        return "дернули поле $name";
    }
}

Зачем было использовать именно этот термин - перегрузка?! Пыха-стайл блин 😂

Далее у нас термин замыкание. Обычно это функция вместе с её лексическим окружением (то есть переменными, которые видны в месте её определения). И эта функция может запоминать эти переменные "подолгу", и у другой функции-замыкании эти значения переменных уже будут свои.

Вот пример на питоне:

# Python
def make_counter():
    count = 0
    def add():
        nonlocal count
        count += 10
        return count
    return add

counter = make_counter()
print(counter())  # 10
print(counter())  # 20

Возвращаемый add будет помнить count из своего окружения. Такое же в JS, Kotlin и Go.

А что документация PHP нам говорит?
https://www.php.net/manual/en/functions.anonymous.php
Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callable parameters, but they have many other uses.
Согласно документации, замыкание в пыхе - это тупо анонимная функция 😂 Нафига так было писать?

Честности ради можно сказать, что классическое замыкание в PHP можно повторить.

// PHP
function makeCounter() {
    $count = 0;
    return function() use (&$count) {
        $count += 10;
        return $count;
    };
}

$counter = makeCounter();
echo $counter();  // 10
echo $counter();  // 20
Show full...
+2
2

Por qué return await en JS no siempre es malo, sino todo lo contrario: es lo correcto

Algunos desarrolladores de JS se hacen los listos y dicen que en vez de:
return await someService.doSomething();
hay que escribir:
return someService.doSomething();

O sea, si una función async devuelve una promesa en su return, el resultado de resolver esa promesa se convierte automáticamente en el valor de retorno real. Es decir, las promesas se "desempaquetan" de forma recursiva.

Todo esto suena bien, pero hay un problema bastante serio. Miren este código:
// Técnicamente esta función devuelve una promesa,
// pero en realidad lanza un error
async function fun1() {
  throw new Error('Hi from Famabara!');
}
(async () => {
  try {
    return await fun1();
  } catch (err) {
    console.log('Error catched!', err);
  }  
})();

Aquí todo va bien, el error se captura en el bloque catch. Pero si lo escribimos así:
async function fun1() {
  throw new Error('Hi from Famabara!');
}

try {
  (async () => {
    try {
      return fun1();
    } catch (err) {
      console.log('Error catched!', err);
    }  
  })();
} catch (err) {
  console.log('Error catched!', err);
}
¡entonces ninguno de los dos bloques catch captura el error! Esto es una desventaja tremendamente grave. El error simplemente no se puede capturar de ninguna manera, a menos que uses el método catch() directamente sobre la promesa, si no escribes await.

En fin, la recomendación de no escribir return await es una muy mala recomendación. Directamente perjudicial.
Show full...
+1
1

Warum return await in JS nicht immer schlecht ist, sondern im Gegenteil sogar richtig

Manche JS-Entwickler tun schlau und behaupten, dass man statt:
return await someService.doSomething();
lieber schreiben sollte:
return someService.doSomething();

Nach dem Motto: Wenn eine async-Funktion in ihrem return ein Promise zurückgibt, wird ja sowieso das Ergebnis der Auflösung dieses Promises zum eigentlichen Rückgabewert. Promises werden also quasi rekursiv "entpackt".

Das klingt erstmal plausibel, aber es gibt ein ziemlich ernstes Problem dabei. Schaut euch mal diesen Code an:
// Technisch gibt diese Funktion ein Promise zurück,
// wirft aber in Wirklichkeit einen Fehler
async function fun1() {
  throw new Error('Hi from Famabara!');
}

(async () => {
  try {
    return await fun1();
  } catch (err) {
    console.log('Error catched!', err);
  }
})();

Hier ist alles in Ordnung, der Fehler wird im catch Block abgefangen. Schreibt man es aber so:
async function fun1() {
  throw new Error('Hi from Famabara!');
}

try {
  (async () => {
    try {
      return fun1();
    } catch (err) {
      console.log('Error catched!', err);
    }  
  })();
} catch (err) {
  console.log('Error catched!', err);
}
dann fängt keiner der beiden catch Blöcke den Fehler ab! Das ist ein wirklich heftiger Nachteil. Der Fehler lässt sich dann gar nicht mehr abfangen - man müsste zwingend catch() direkt auf dem Promise aufrufen, wenn man kein await verwendet.

Kurz gesagt: Die Empfehlung, kein return await zu schreiben, ist eine sehr schlechte Empfehlung. Geradezu schädlich.
Show full...
+1
1

Забудьте про ESLint, используйте Oxlint как основной линтер в JS/TS

На проекте разрешили попробовать сменить ESLint на Oxlint. После первого запуска я выпал, даже не понял, что программа отработала 😄 Настолько съело быстро, что не замечаешь, т.е. нажимаешь Enter и уже сразу результат. Ты вообще не ждешь. 😎

Короче, не будем пробовать менять, будем полностью менять на о-экс-линт без попробовать. Зачем нужен еслинт теперь? Каждый коммит - медленная проверка, линтер в ci/cd - медленная проверка. У нас теперь все будет летать.

Сколько выполняется линтинг на eslint? Запускаю через time:
time npm run lint

real    0m10,108s
user    0m12,620s
sys     0m1,264s
Выполняется 12-13 секунд. Секунд!!! Это 12000-13000 мс.

Запускаю прикрученный oxlint:
npm run lint2

Found 0 warnings and 0 errors.
Finished in 67ms on 1044 files with 57 rules using 16 threads.

Офигеть не встать. У меня получилось в 180 раз быстрее.
Поддерживает из коробки Typescript. Куча встроенных правил уже есть, кучу хрен знает каких плагинов добавлять не нужно. Можно комментировать строки по аналогии с еслинтом. Разрешить консоль на следующей строке:
// oxlint-disable-next-line no-console

Изучаю его дальше, но наши челы уже согласны переходить. Но пока заметил серьезный минус - нет стилистических правил. Например, правила 'no-multi-spaces' из классического еслинта нет, нужно каким-то кривым образом прикручивать, а нам это правило нужно. Есть рекомендация использовать в oxlint еслинтовый пакет @stylistic/eslint-plugin, но это уже похоже не бред. И поставить его нельзя отдельно нормально, в peer dependencies сидит eslint. 😄 С этим засада, короче.

Я поставил @stylistic/eslint-plugin и отдельно eslint, подключил правило '@stylistic/no-multi-spaces' в oxlint - время проверки выросло:
Found 0 warnings and 1 error.
Finished in 495ms on 1044 files with 58 rules using 16 threads.
Уже 495 мс - это из-за жса.
Подключил все правила из @stylistic/eslint-plugin (примерно 80 штук), стало выполняться за 1 секунду.

Есть ещё Oxfmt для форматирования. Им теоретически можно решить проблему стилизации, но это в первую очередь принудительный форматтер, а не линтер, а нам нужен именно линтер. Форматтер не всегда хорошая штука.
Show full...
+2
10

How the size of the node_modules directory grows: the Nuxt example

Daniel Roe (author of Nuxt) reports that a new npm package will now be used for route analysis:

We've migrated Nuxt's file-system route generation to unrouting (#34316), which uses a trie data structure for constructing routes. The cold start is roughly the same (~8ms vs ~6ms for large apps), but dev server changes are up to 28x faster when you're not adding/removing pages, and ~15% faster even when you are.

https://github.com/nuxt/nuxt/releases/tag/v4.4.0

Performance improvements are always good. But what's happening under the hood? Looking at the GitHub changes:
Show full...
+2
8

Джуны и мидлы не нужны: неделю использую Claude Code в качестве агента (личный опыт)

Пугалка становится реальностью, а маркетинговая чушь от авторов нейросетей не такая уж и чушь.

Неделю пишу код, взяв в помощники Claude Opus 4.7 от Anthropic (через расширение для VS Code). Тариф самый дорогой, поэтому токены не экономлю. Общее ощущение - восторг. Пишу и бэк и фронт.

Клод отлично понимает, что мне нужно, когда я ему чётко говорю, что сделать. Важно кратко, но точно указать, что именно нужно ему сделать и в каком стиле написать. По поводу стиля - почти всегда хватает написать что-то вроде "пиши по аналогии с другими методами". Русский язык понимает прекрасно, нет смысла писать на английском.

Значительная экономия времени. То, на что я бы потратил 3 дня, с Claude Code я сделал за 3 часа. Тесты так вообще пишет очень быстро, и даже сам запускает для перепроверки, а это такая унылая рутина. С тестами надо обязательно указать моменты, которые мы проверяем, чтобы тесты были реально тестами, а не бессмысленными заглушками.

Я перестал бояться потери навыков. :) Стал больше концентрироваться на архитектуре. Чем меньше ему даёшь работы по объёму, тем лучше код, т.е. задачи надо декомпозировать. Конечно, Клод не знает всего огромного контекста проекта и того, что у тебя в голове. Он просто быстрый и умный исполнитель. Но иногда даже видит вещи, которые я сам бы не увидел; часто пишет лучше, чем я бы сам написал, находя опасные моменты, дописывая там дополнительные проверки на пограничные случаи.

Тут важно самому не лениться и тщательно перечитывать сгенерированный код. Т.е. бОльшую часть времени работы ты делаешь код-ревью. Здесь можно сорваться и всё сразу коммитить. Так делать нельзя!!! Надо перепроверять! Claude Code - это очень толковый усердный мидл, который не знает усталости (тариф максимальный). Он ошибается, а ты ему говоришь, где исправить. Изредка сам вручную меняешь, иногда так быстрее.

Так вот, мой вердикт - джуны и мидлы теперь не нужны. Реально, парой сеньоров можно заменить команду из 6 человек. Лично моя работа ускорилась. Понимаю, что теперь ситуация для рынка IT-вакансий крайне фиговая. Останутся только профессионалы, а джуны вообще больше будут не нужны. Мидлы нужны максимум, чтобы вырастить нового сеньора.

Делает ли Клод ошибки? Конечно, делает, кто ж их не делает. Кожаные мешки тоже ошибаются, но ревью кода никто не отменял.

Не знаю, какие цены будут дальше на агента, говорят же, что все нейросети дико убыточны. Но один клод-код на максимальном тарифе всё равно дешевле зп мидла и уж тем более джуна. Всё это вызывает смесь восторга с какой-то оторопью.

Рынок будет сильно меняться. Не все осознали мощь платных нейросетевых агентов, я тоже раньше скептически относился. Кто не в теме, уйдёт с рынка рано или поздно. В общем, IT (по крайней мере программирование) теперь будет только для синьоров-помидоров.
Show full...
+2
40

Может ли Claude Code удалить посторонние файлы или выполнить rm -rf

Щупаю Claude Opus 4.7 по тарифу Max. Штука очень мощная, ускоряет работу, если правильно пользоваться, особенно приятно Клоду поручить рутину.

Агент Claude работает из терминала. Даже если это extension в IDE, то он постоянно отправляет запросы в bash, всё время спрашивая разрешение.
В заголовке поста был вопрос: может ли Claude Code удалить посторонние файлы или выполнить rm -rf? Ответ - да, может. Вообще не проблема для него. Вся защита от опасных команд смехотворна. Вот это вот ни от чего не защитит:
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)",
      "Bash(git * main)",
      "Bash(* --version)",
      "Bash(* --help *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

Кто знает линукс, тот знает, что можно легко запайпить вторую команду или написать её так, что простым сравнением не найдётся, то есть обфусцировать. Ещё Клод Код часто запускает пайтоновские скрипты для автоматизации своих действий, всё хранит в tmp каталоге. А что он там написал в пайтоновском скрипте - не показывается. Пайтоном можно делать всё что угодно. И объёмные скрипты на баше он активно генерирует, а потом просит их запустить.

В общем, тут или доверять Клоду полностью или делать вид, что ты "защитился" с помощью строчек в permissions.
Show full...
+2
28

В США впервые смогли доказать что социальные сети вредят детям

25 марта в Лос-Анджелесе присяжные признали Meta Platforms Inc.* и Google виновными в причинении вреда здоровью молодой американки.

Суть претензий

Девушка утверждала, что начала пользоваться YouTube в шесть лет, а Instagram** — в девять. По ее словам, дизайн платформ и система рекомендаций вызвали у нее зависимость, что привело к неврозам, агрессии, депрессии и дисморфофобии (полному неприятию своего внешнего вида).

Адвокат истицы сосредоточился на том, как компании подают контент, а не на его содержании. В качестве доказательства он привел переписку сотрудников, где обсуждалась зависимость пользователей как бизнес-модель.

Решение суда

Компании обязаны выплатить девушке 2,1 миллиона долларов и оплатить курс психологической реабилитации. В будущем суд определит размер штрафов.

Это первый случай, когда такой иск был удовлетворен полностью. Юристы считают, что решение может изменить правила работы интернет-платформ, обязав их предупреждать о рисках для детей и вводить дополнительные меры безопасности. Значение дела сравнимо с делом против табачных компаний 1990-х годов, когда удалось доказать, что они скрывали вред курения.

Несколькими днями ранее другой суд в США также обязал Meta* выплатить $375 млн за то, что компания ввела пользователей в заблуждение относительно безопасности своих платформ для детей. Сами IT-гиганты не признают свою вину и планируют обжаловать решения суда. Однако, похоже, для них это стало только началом сложного периода. Теперь у Meta* и Google есть только два варианта: либо они изменят принцип работы, либо постепенно их бизнес-модель рухнет, как это было со многими табачными компаниями после знаменитого суда в 90-х.

*Признана экстремистской организацией, запрещена в РФ.
**Принадлежит компании Meta, признанной экстремистской организацией, запрещена в РФ
+4
132

Никто не пишет RIGHT JOIN в SQL

Пост для айтишников бэкендеров.

Вы кого-нибудь писали в реальном коде RIGHT JOIN? Не в учебном, а в настоящем коде, который ушёл в продакшн. У меня не так много лет опыта, но я вот ни разу не писал. Поспрашивал у своих, те тоже никто не писал ни разу, даже те, кто уже десять лет на бэке.

В стандарте SQL есть правый джойн, но им никто не пользуется. Он же контринтуитивен! Зачем мне "обрезать" главную таблицу, написанную слева и подсоединять к полной правой? Логично же поменять их местами и написать LEFT JOIN.
+2
28

Misleading naming in JavaScript: atob() and btoa()

JavaScript has two globally available metods for working with Base64: atob() and btoa(). Their names clearly look like they were borrowed from older languages. In C, for instance, the standard library includes functions like atoi and atof:

<