LINUX.ORG.RU
ФорумTalks

В Ubuntu 25.10 решено заменить GNU Coreutils на uutils, написанные на Rust

 , , , uutils


0

4

Замена коснётся более ста утилит, входящих в состав Сoreutils, включая sort, cat, chmod, chown, chroot, cp, date, dd, echo, hostname, id, ln и ls. В настоящее время утилиты uutils уже применяются по умолчанию в дистрибутиве Apertis, основанном на Debian, а также в независимом дистрибутиве AerynOS (SerpentOS). Опубликованный на прошлой неделе выпуск пакета uutils coreutils 0.0.30 успешно проходит 507 тестов (в прошлом выпуске 506, в позапрошлом - 476) из эталонного тестового набора GNU Coreutils. 69 тестов завершилось неудачей, а 41 тест был пропущен. В ближайшие недели также планируется приступить к работе над заменой в Ubuntu утилит su и sudo на пакет sudo-rs. Из рассматриваемых проектов дополнительно упоминаются zlib-rs и ntpd-rs.

Если эксперимент будет признан удачным, то uutils также будут задействованы по умолчанию в LTS-ветке Ubuntu 26.04.

★★★★★

Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от LightDiver

это какой-то ублюдичный овнокод:

  1. три нотации кодирования в 5и строчках

  2. конструкции не несущие бизнес-смысла типа анврап, ни один друсткод без них не обходится, если вам платят за удовлетворение компилятора ок, но в опенсорсе какой толк от такого уродства?

  3. шизоидное структурирование и бесконечными уровнями вложенности. Зачем надо оборачивать with_template если передаем мы по факту строковый литерал шаблона? Почему не убрать это «под капот»? Я отвечу. Потому что в друсте нет ООП и все пишут код кусками образующими кашу

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 3)
Ответ на: комментарий от LightDiver

а точка с запятой после возвращаемого значения не ставится в отоичии от остальных строк чтобы еще кросивше было?

Syncro ★★★★★
()
Ответ на: комментарий от Syncro

Ну лень им обрабатывать исключения. Бывает.. При чем тут удовлетворение? Просто особенности языка, что обработка должна быть. Это самый минимальный ее вариант и все.

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

LightDiver ★★★★★
()
Ответ на: комментарий от Syncro

В Rust выражение возвращает значение, а инструкция нет. Просто синтаксис языка. Вместо ретерна - то где нет точки с запятой, становится возвратом значени и все.

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

Говорю же - надо просто привыкнуть к синтаксису.

LightDiver ★★★★★
()
Ответ на: комментарий от Syncro

Что не так то? Зачем тебе писать лишнее слово в конце, если и так понятно, что это возврат? Просто не ставь точку с запятой и все.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

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

Syncro ★★★★★
()
Ответ на: комментарий от LightDiver

когда я захочу сделать свой синтаксический анализатор этого «кода», придется его накостыливать для поддержки этих особенностей или плотить ИИ чтобы разобрался

Syncro ★★★★★
()
Ответ на: комментарий от Syncro

Слушай, ну вот смотри. Не нравится тебе тот же анврап. Но что он делает? При панике и ошибке срабатывает макрос паник, он вызывает деструкторы, разматывает стек, очищает все, уничтожает, что нужно уничтожить. Хорошо же.

В том же си в этом случае все просто засрется, я правильно понимаю? Си тут явно не выигрывает.

И заметь, это самый минимальный механизм обработки ошибки. Без матча, без условий и прочего. Просто минимальный безопасный способ все очистить, если вдруг что не так. И ты не забудешь о нем - компилятор не позволит.

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

это называется «закат солнца руками» и зачем уничтожать если дальше приложение будет выгружено?

Syncro ★★★★★
()
Ответ на: комментарий от LightDiver

если компилятор всегда знает, где должен быть анврап зачем программиста заставлять его везде вызывать явно? Чтобы он сразу ощущал себя виноватым?

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 1)
Ответ на: комментарий от Syncro

Ну, во-первых, приложение может быть не выгружено, если падает дочерний процесс.

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

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

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

Короче, разница в том, что в раст этот момент хотя бы продумали и сделать хоть какую то обработку.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Возможно, восприняли всерьез заявления правительственных организаций о том что хорошо бы избегать небезопасных языков

cobold ★★★★★
()
Ответ на: комментарий от LightDiver

Чтобы тебе не пришлось вчитываться есть там в конце точка с запятой или нет. Слово return визуально более заметно и однозначно понятно что имел в виду автор. А тут? Забыл он про точку с запятой или не забыл?

cobold ★★★★★
()
Ответ на: комментарий от cobold

Да хрен знает, если нет точки с запятой, это ВСЕГДА может быть только в конце функции. Ты и так всегда знаешь о такой особенности и видишь ее. Ты же знаешь, что функция может возвращать результат? Видишь - нет точки с запятой. Значит это возврат. Просто убрали лишнее слово и все.

Ладно бы это было где то в середине и нужно было искать.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Ну, во-первых, приложение может быть не выгружено, если падает дочерний процесс.

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

и нас сразу предупредили - не юзать его в нормальных проектах

ага, «вы все - говно»

Короче, разница в том, что в раст этот момент хотя бы продумали

разница в том, что его особенности не от наивности или немощи создателей, а чтобы дефекты позволяли терроризировать разработчиков, ритуализировать процессы, качелить на эмоциях, кидать на деньги и не только, принуждать к преступлениям и переездам

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 1)
Ответ на: комментарий от Syncro

Просто созданы различные механизмы обработки. Да, заставляют их использовать. И правильно делают. Не надо забывать это все обрабатывать. Бери и обрабатывай нормально.

У тебя нет искушения просто «забыть все» или забить. Если ты так сделал - ты это сделал намеренно. Целенаправленно. Понимаешь разницу?

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Единственное чего нет из ООП - наследования, так есть композиция.

совместимости с базовым типом по умолчанию там нет. но вам запудрили мозги «лучшестью» композиции вместо наследования.

еще там ссылки или одна на модификацию или много на чтение. отчего праксисски невозможно работать с абстракциями навроде Декоратора или ЮзКейза, и подобных. то есть определяющих новые свойства через ссылку на старый обьект.

не знаю всех темных мест вашего раста, но проблемы с реализацией сложных архитектур на этом вашем расте очевидны.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Да мне никто мозги не запудривал. Я вообще месяц назад понял что такое ООП. Мне хоть композиция, хоть наследование - один хрен. Я пользуюсь одним, пользуюсь другим сейчас.

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

LightDiver ★★★★★
()

Работа кипит. Еще немного, и в убунте смогут полностью сделать то, что уже и так давно есть!

thesis ★★★★★
()
Ответ на: комментарий от LightDiver

Мне хоть композиция, хоть наследование - один хрен

значит ты не понял ООП. это существенно разные вещи, иначе их бы не формулировали специальным образом.

alysnix ★★★
()
Ответ на: комментарий от LightDiver

Избавились от мусора

(Self::No { .. }, Self::No { .. }) => Ordering::Equal,
    pub const LINKS: Self = Self {
        links: Preserve::Yes { required: true },
        ..Self::NONE
    };
fn handle_preserve<F: Fn() -> CopyResult<()>>(p: &Preserve, f: F) -> CopyResult<()> {
fn aligned_ancestors<'a>(source: &'a Path, dest: &'a Path) -> Vec<(&'a Path, &'a Path)> {

Как-то вы не в ту сторону от него избавились.

(код из сабжевого варианта cp)

micronekodesu ★★★
()
Ответ на: комментарий от alysnix

Ну разные. Но я могу сделать одну и ту же задачу и тем и тем способом. В целом понимаю их разницу и что они делают.

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

Что изменилось бы, если бы я использовал композицию? Я бы в новом классе просто создал экземпляр старого и работал бы через него. Все. Результат один и тот же, подходы чуть чуть разные.

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

LightDiver ★★★★★
()
Ответ на: комментарий от micronekodesu

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

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Что изменилось бы, если бы я использовал композицию? Я бы в новом классе просто создал экземпляр старого и работал бы через него. Все. Результат один и тот же, подходы чуть чуть разные.

нет. в первом случае ты смог бы вызывать функции базового класса со ссылками на обьект нового класса. в силу совместимости наследника с базовым по ссылке.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Еще раз. Я в новом классе создаю экземпляр старого класса. У меня он есть в таблице нового класса. Все. Я через это и работаю.

Смотри. В конструкторе старого класса я указываю с какой таблицей работать.

NsDb = {}
NsDb.__index = NsDb

-- Конструктор для создания нового объекта NsDb
function NsDb:new(input_table, input_table_p, key, str_len)
    local new_object = setmetatable({}, self)
    new_object:init(input_table, input_table_p, key, str_len)
    return new_object
end

-- Инициализация объекта
function NsDb:init(input_table, input_table_p, key, str_len)
    self.input_table = self:initializeTable(input_table, key)
    if input_table_p then
        self.input_table_p = self:initializeTable(input_table_p, key)
    end
    if str_len then
        self.str_len = str_len
    end
    self.isPointer = input_table_p and true or false

    -- Инициализация переменных состояния
    if self.isPointer then
        if #self.input_table_p == 0 then
            self.last_str_addr = 0
            self.str_count = 0
        else
            -- Считаем количество строк и размер последней строки
            self.str_count = 0
            self.last_str_addr = en10(self.input_table_p[#self.input_table_p]:sub(-2):gsub("^%s", ""))
            for i = 1, #self.input_table_p do
                self.str_count = self.str_count + 1
            end
        end
    end
end

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

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

это вообще не ооп. а настольная модель ооп в размере 1:50, для склейки и раскрашивания.

вот ооп:

///нечто с массой
class Massive {
  int _mass = 0;
public:
  void set_mass(int fmass) {_mass = fmass; }
  int print_mass() const {... prints the mass here... }
}

///массивная сфера
class Sphere: public Massive {
  int _radius = 0;
}

///массивный куб
class Cube: public Massive {
  int _size = 0;
}

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

а с наследованием все чисто.

{
  Cube cub; cub.set_mass(10); cub.print_mass();
  Sphere sp; sp.set_mass(20); sp.print_mass();
}
alysnix ★★★
()
Ответ на: комментарий от alysnix

Ладно, мы явно друг друга не понимаем. Сначала изучу основы раст, си, с++, поработаю с ООП в них и потом может еще побеседуем к нибудь.

LightDiver ★★★★★
()
Ответ на: комментарий от LightDiver

Но я могу сделать одну и ту же задачу и тем и тем способом. В целом понимаю их разницу и что они делают.

Какой хуже, какой лучше - я лично сказать не могу.

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

Представь ты делаешь оплату в онлайн-магазине. У тебя есть класс PaymentProcessor, у которого есть метод pay(amount). Потом ты наследуешь этот класс, делаешь PayPal(PaymentProcessor), SBP(PaymentProcessor), YandexMoney(PaymentProcessor) и так далее, все они могут в этот pay(amount), но под капотом они разные.

И у тебя есть объект заказа, в котором список покупок, расчет суммы, скидки и все такое, и он должен выполнить оплату через этот PaymentProcessor. Ты можешь, конечно, запихнуть весь код с заказом в базовый класс платежного класса, но тогда ты в одном месте смешиваешь разные по природе данные. В этом случае у тебя уже используется композиция, типа

class Order:
    def __init__(self, payment_processor: PaymentProcessor):
        self.payment_processor = payment_processor

    def checkout(self):
        price = self.calculate_price()
        self.payment_processor.pay(price)

И сюда ты передашь уже процессор для выбранного способа оплаты при инициализации.

(пример не самый удачный, потому что на самом деле ордеру не нужно знать про payment_processor, хорошо бы сделать композицию где будут отдельно ордер и процессор, но это будет еще больше текста в сообщении)

micronekodesu ★★★
()
Последнее исправление: micronekodesu (всего исправлений: 1)
Ответ на: комментарий от LightDiver

А с переходом на раст выдают 21:9 монитор и шейный экзоскелет?

BceM_IIpuBeT ★★☆☆☆
()

Интересно зачем? Тут же есть два варианта:
1. Постоянно играть в догонялки. В coreutils появляется что-то новое, мы спешим это новое запилить и у себя.
2. Мы все больше и больше уходим от coreutils пиля что-то свое неповторимое.
ИМХО и первый и второй вариант ну такое себе.

anc ★★★★★
()
Ответ на: комментарий от sparkie

До первого апреля ещё полмесяца.

Я тоже на календарь сначала посмотрел.

anc ★★★★★
()
Ответ на: комментарий от LightDiver

Даже если мы их не понимаем, это еще не значит, что там дебилы сидят.

Мне кажется все-таки в обратной последовательности.

anc ★★★★★
()
Ответ на: комментарий от MoldAndLimeHoney

Эти утилиты и так потеряли возможность к развитию.

Почитайте changelog-и и сравните с такими же от других систем.

anc ★★★★★
()
Ответ на: комментарий от LightDiver

Охренеть! Они прогрессбар при копирование реализовали!

Уже было. man rsync.

anc ★★★★★
()
Ответ на: комментарий от LightDiver

Не, если без шуток - я то сам в восторге от раста, но такого перфоманса вообще не понял.

Всё на свете нужно переписать на расте же. Что ты не понимаешь?

skiminok1986 ★★★★★
()
Ответ на: комментарий от th3m3

Ещё бы snap выкинуть и норм дистр станет.

Не выкинуть, а переписать на rust.

skiminok1986 ★★★★★
()
Ответ на: комментарий от LightDiver

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

Что очередной раз доказывает, что «переписывать весь мир на расте» посадили макак, которые не знают базовых концепций языка

PPP328 ★★★★★
()
Ответ на: комментарий от dataman

Какая разница где это ещё сделано? Важно когда это есть в базовой поставке. Я вот пишу скрипт, который распространяю, и я не могу завязываться на какой-то там nnn, я могу использовать только утилиты из базовой поставки. И если во всех линуксах cp будет иметь возможность показывать прогресс - это будет здорово.

Loki13 ★★★★★
()
Последнее исправление: Loki13 (всего исправлений: 1)
Ответ на: комментарий от micronekodesu

А что мешает мне реализовать все эти способы оплаты методами в классе?

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

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

Допустим моя база данных. Я могу не делать методы для работы с каждым типом таблиц. Допустим, у меня только инициализация в базовом классе: он принимает таблицы, принимает параметры. Все.

Затем я создаю класс работы с хэш-таблицами. В нем создаю наш базовый экземпляр. Через него методами нового класса работаю с чем надо.

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

Я понимаю разницу, понимаю варианты работы. И вижу с чем как можно работать. Мне доступны все методы старого класса, доступны методы нового. Просто чуть иначе, чем при наследовании. При наследовании они доступны как просто методы нового класса. При композиции, через параметр нового класса. И вся разница.

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

LightDiver ★★★★★
()
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

А что мешает мне реализовать все эти способы оплаты методами в классе?

Чисто технически - ничего. Все эти «правила разработки» это не технические ограничения, а то как делать чтоб потом было проще. Если ты в одном классе намешаешь логики из разных «областей» тебе будет потом сложнее с этим работать и переиспользовать. Если ты все варианты оплаты сделаешь методами в одном классе то у тебя получится каша (потому что там не только pay будет, а еще куча логики с какими-нибудь авторизациями, подготовкой пэйлоада и прочего, а если у тебя в классе кроме инита есть только один метод то в 99% случаев класс тебе и не нужен, хватит функции) и ты не сможешь выделить нормальный интерфейс.

При наследовании они доступны как просто методы нового класса. При композиции, через параметр нового класса. И вся разница.

Да дело не в том как работает код, эта история про «логику», чтоб человеку было понятно что от чего зависит и что с чем взаимодействует.

micronekodesu ★★★
()
Ответ на: комментарий от micronekodesu

Я все это понимаю. Я потому и сделал наследование, чтобы было проще работать.

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

LightDiver ★★★★★
()
Ответ на: комментарий от Loki13

завязываться на какой-то там nnn

И не нужно, там патчи для cp и mv, но не для последних версий.

я могу использовать только утилиты из базовой поставки. И если во всех линуксах cp будет иметь возможность показывать прогресс - это будет здорово.

Понимаю. Тогда $ man progress, хоть и костыль.

dataman ★★★★★
()

Давайте уж сразу на Node.js, к чему эти промежуточные варианты.

И как там насчёт внедрения AI? А то не в тренде совсем!

vsnb
()
Последнее исправление: vsnb (всего исправлений: 1)
Ответ на: комментарий от vsnb

Если бы были доступные быстрые локальные варианты, это бы уже было внедрено везде. Я бы первый не откаался. Просто сейчас это сложнее. Но мы на заре технологии, будет все еще.

LightDiver ★★★★★
()
Ответ на: комментарий от alysnix

а с наследованием все чисто.

Хех, а потом понадобится миллиард массивных объектов для какой-нибудь симуляции и придётся тащить гигабайтный оверхед на аллоцирование памяти под каждый объект, потому что размеры у них разные и сложить их в один массив не получится.

red75prim ★★★
()
Ответ на: комментарий от LightDiver

как сделать так же через композицию

Речь про этот пример?

Допустим моя база данных. Я могу не делать методы для работы с каждым типом таблиц. Допустим, у меня только инициализация в базовом классе: он принимает таблицы, принимает параметры. Все.

Затем я создаю класс работы с хэш-таблицами. В нем создаю наш базовый экземпляр. Через него методами нового класса работаю с чем надо.

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

Так не обязательно выбирать что-то одно. Таблицы могут наследовать базовый класс\интерфейс таблиц, а в классе БД при этом будет композиция с объектами таблиц. Если у классов для таблиц общий интерфейс классу БД нужно знать только его, как что реализовано у таблиц под капотом ему не важно. Также потом ты можешь создать другой вариант БД (например ты хранишь на диске, а за хочешь в памяти) - пока все БД наследуют базовый интерфейс классам таблиц (если они дергают класс БД) не нужно от конкретного класса БД зависеть, ты можешь при инициализации нужный вариант передавать а не переписывать код чтоб переключиться с хранения на диске на хранение в памяти.

micronekodesu ★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)