Libelektra: Caracteres reservados em nomes-chave

Criado em 16 nov. 2019  ·  62Comentários  ·  Fonte: ElektraInitiative/libelektra

Proponho que os seguintes caracteres sejam reservados e escapáveis ​​(para remover o significado especial) nos nomes de chave:

  • []% (já usado para nomes vazios e valores contextuais)
  • [] # (é usado para matrizes, consulte # 2698)
  • [] _ (é usado para globbing)
  • [] * (é usado para globbing)
  • [] e (não utilizado)
  • []? (não utilizado)
  • [] @ (é usado para se referir a parentKey, por exemplo, no plug-in condicional)
  • [] (usado para se referir à própria parte do nome da chave, ou uma acima)
  • [] / (para separar caminhos)
  • [] \ (para escapar)

O que você acha?

low priority proposal question

Todos 62 comentários

Veja também # 2698 para uma discussão sobre qual caractere ser usado para array (globbing)

Em primeiro lugar, se você listar \ , também deverá colocar / na lista. A barra é claramente o caractere prototípico reservado (caractere com significado especial) em Elektra.

Em segundo lugar, "usado para globbing" e "usado para referir-se a parentKey, por exemplo, no plug-in condicional" não são casos de uso válidos aqui. Estes não são significados especiais durante o unescaping. Se você quiser evitar uma interpretação especial que aconteça mais tarde (por exemplo, por um plug-in ou biblioteca), você deve saber que essa interpretação é baseada no nome da chave de escape (o que seria ruim, conforme descrito em https: // github. com / ElektraInitiative / libelektra / issues / 2698 # issuecomment-554636250), ou você deve garantir que o nome sem escape não possa ser interpretado de maneira especial.

Vamos tomar # como exemplo. Nossa biblioteca globbing interpreta o nome da chave /a/# como significando "corresponder a qualquer elemento do array /a ". Se não quisermos isso, mas quisermos corresponder /a/# literalmente, precisamos usar algum tipo de escape. No entanto, /a/\# não pode funcionar. O que a barra invertida alcança durante a remoção do nome da chave? Para evitar a interpretação especial da biblioteca globbing, ela teria que permanecer lá durante o unescaping. Mas isso viola a regra (°) de que uma barra invertida deve ser escapada, se não for um caractere de escape em si (não é um caractere de escape, se não desaparecer durante o unescaping). Portanto, precisamos usar /a/\\# , que não terá escape em ⊙a⊙\# (⊙ no lugar de NUL, namespace e terminador omitidos). Mas, nesse caso, # não tem nenhum significado especial para nome de chave sem escape e não precisa ser considerado de forma alguma.

Em outras palavras, para dar uma razão pela qual um caractere deve escapar (por que está reservado), você deve pensar sobre _ "Qual comportamento de elektraKeyNameCanonicalize ou elektraKeyNameUnescape evitaria o escape?" .


Para os personagens que realmente queremos "reservados", há uma decisão que devemos tomar aqui. Esses _caracteres têm significado especial_ ou _caracteres reservados_ reais?

Em minha opinião, _caracteres com significado especial_ são caracteres normais que podem ser usados ​​como tal, mas podem ter uma interpretação especial em um determinado contexto (por exemplo, % se for a parte chave inteira).

Os _caracteres reservados_, por outro lado, são reservados para contextos especiais. Eles não podem ser usados ​​normalmente e são permitidos apenas em contextos especiais, nos quais têm um significado especial.

Um _caractere com significado especial_ só precisa ser escapado no contexto, no qual tem sua interpretação especial, se esta interpretação especial não for desejada. Fora deste contexto, o escape pode ser permitido ou não, dependendo da nossa posição sobre o escape desnecessário (°°).

Um _caractere reservado_, por outro lado, deve ser escapado sempre que não tiver nenhum significado especial. Isso significa que, no contexto em que tem um significado especial, pode ser escapado, para evitar o significado especial. Fora deste contexto, deve ser escapado.

Como exemplo, vamos olhar para % . Se uma parte da chave inteira for apenas % (por exemplo, /%/ ), esta parte não tem escape em uma parte vazia. Em ambos os casos, a barra invertida em /\%/ impedirá a interpretação especial e ficará sem escape em uma parte que é % . A diferença torna-se perceptível, no entanto, se olharmos para contextos diferentes, como /a%b/ .

Se tratarmos % como um _caractere reservado_, então /a%b/ é uma parte / nome de chave ilegal e devemos gerar um erro. A maneira correta de obter a parte sem escape a%b com um _caractere reservado_ seria usando /a\%b/ .

Se virmos % como um _caractere com significado especial_, então /a%b/ estaria correto e não escaparia para a%b . Novamente, se /a\%b/ também é permitido, depende de nossa postura quanto ao escape desnecessário. Se for permitido, também desfaz o escape em a%b .

Nota: Para / não há decisão, ambas as interpretações são equivalentes, já que não há contexto, no qual / não tem significado especial. Para \ já decidimos (em # 3115) tratá-lo como um _caractere reservado_ e, portanto, requerer escape, quando não for usado como um caractere de escape em si.


A decisão acima, claro, também nos obriga a definir, em que contextos podem esses personagens, agora ou no futuro, têm significados especiais.

Existem duas soluções fáceis aqui:
Trate tudo (exceto / e \ ) como _caracteres com significado especial_, permita escapes desnecessários e para os não usados ​​defina que tenham uma interpretação especial em todos os contextos. A interpretação especial para esses seria que eles tornam um nome de chave ilegal. Portanto, os não utilizados sempre devem ser escapados. Qualquer outro caractere da lista pode sempre ter escape, mas só deve ser, se quisermos evitar uma interpretação especial específica.

---

(°) Conforme declarado em # 3115, esta regra torna todo o sistema muito mais fácil de entender. Em um nome de chave com escape (válido), uma barra invertida sempre escapa de algo. Em um nome de chave sem escape (válido), uma barra invertida é sempre literalmente uma barra invertida.

(°°) Se adotarmos uma postura muito rígida sobre escape desnecessário, deve ser possível obter uma relação de 1: 1 entre nomes de chave com escape e sem escape. É claro que isso requer mais esforço na validação de nomes de chave e, portanto, terá um impacto no desempenho (se esse impacto for de alguma forma significativo deve ser testado).

Em primeiro lugar, se você listar \, também deverá colocar / na lista. A barra é claramente o caractere prototípico reservado (caractere com significado especial) em Elektra.

Obrigado, eu adicionei. Se você encontrar mais personagens, você pode simplesmente adicioná-los à postagem superior.

Em segundo lugar, "usado para globbing" e "usado para referir-se a parentKey, por exemplo, no plug-in condicional" não são casos de uso válidos aqui. Estes não são significados especiais durante o unescaping.

Sim, é claro que também podemos usar outro caractere de escape ou dois \ para alguns desses caracteres. Mas isso vai ser mais complicado para os usuários?

O que a barra invertida alcança durante a remoção do nome da chave?

Eu tinha em mente que keyAddBaseName (key, "_") adicionará \_ . Portanto, para obter um _ (com o significado do caractere globbing), você precisaria usar keyAddName.

Por exemplo, @sanssecours atualmente usa _ dentro de nomes de chave para o plugin directoryvalue. É claro que não há como escapar disso, já que esses mecanismos de escape não são fáceis de escrever. Eu esperava que pudéssemos ter um único local para implementar tal fuga.

Para os personagens que realmente queremos "reservados", há uma decisão que devemos tomar aqui. Esses caracteres têm significado especial ou são realmente caracteres reservados?

Se não tiverem um significado especial agora, serão reservados para que possamos dar-lhes um significado especial mais tarde. Não podemos "reservar" ou "dar um significado especial" posteriormente, pois os aplicativos já podem usar esses caracteres.

Para deixar claro: no post superior, o "significado especial" e "reservado" são sinônimos para o mecanismo de escape. E eu os manteria como sinônimos para facilitar o escape.

Os caracteres reservados, por outro lado, são reservados para contextos especiais. Eles não podem ser usados ​​normalmente e são permitidos apenas em contextos especiais, nos quais têm um significado especial.

Para tornar lógico todo esse mecanismo de escape, eu simplesmente assumiria que os caracteres especiais são sempre especiais, exceto quando são escapados.

Em particular, gostaria de evitar situações em que os caracteres ganham um significado especial se um caractere de escape for adicionado. Este é um hack feio e torna o regex desnecessariamente complicado.

Se virmos% como um caractere com significado especial, então / a% b / estaria correto e não escaparia para a% b.
Mais uma vez, se / a% b / também é permitido, depende de nossa postura quanto ao escape desnecessário. Se for permitido, ele também não escapará para um% b.

Exatamente. O mecanismo não pode impedir totalmente a criação de nomes com significados incorretos. Portanto, acho que não devemos tentar fazer isso. Por exemplo,% nos marcadores de posição precisam ter um número par de ocorrências, mas há exceções. E talvez alguma extensão de valores contextuais irá adicionar mais exceções.

Se adotarmos uma postura muito rígida sobre escape desnecessário, deve ser possível obter uma relação de 1: 1 entre nomes de chave com escape e sem escape. É claro que isso requer mais esforço na validação de nomes de chave e, portanto, terá um impacto no desempenho (se esse impacto for de alguma forma significativo deve ser testado).

Acho que nosso objetivo mais importante deve ser que o escape seja fácil de entender e usar. O escape anterior tentou arduamente para que todos os nomes fossem válidos. Esses objetivos geralmente causam dor de cabeça, mas na verdade não melhoram a usabilidade. Se alguém colocar \ em lugares arbitrários, não há problema em rejeitar alguns nomes. Mas na frente de caracteres especiais, \ deve ser sempre válido e retirar qualquer significado especial (futuro).

Eu tinha em mente que keyAddBaseName (key, "_") adicionará \_ . Portanto, para obter um _ (com o significado do caractere globbing), você precisaria usar keyAddName.

Isso é super confuso para mim ...

A semântica de keyAddBaseName (Key * key, const char * x) é:
x é uma parte sem escape . Ele será adicionado diretamente ao final de key->ukey . Sua forma de escape será adicionada ao final de key->key .

A semântica de keyAddName (Key * key, const char * x) é:
x é um sufixo de nome com escape (ou seja, zero ou mais partes, nenhum namespace). Ele será canonizado e adicionado ao final de key->key . O formulário sem escape será adicionado ao final de key->ukey .

Agora, você deseja que keyAddBaseName (key, "_") adicione a parte \_ ao nome com escape e a parte _ ao nome sem escape. E isso não deve ter nenhum impacto sobre a globalização. Mas keyAddName (key, "_") deve ter significado para globbing, então o que ele faz? _ não pode ficar sem escape de forma alguma, é apenas um único caractere. Portanto, temos que adicionar _ aos nomes com e sem escape. Mas as duas versões produzem o mesmo nome sem escape, o que significa que deve ter o mesmo significado para globbing ...

atualmente usa _ dentro de nomes de chave para o plugin directoryvalue.

AFAIK directoryvalue usa apenas a parte chave /__directoryvalue/ . Isso de forma alguma colide com o uso de /_/ .

Não podemos "reservar" ou "dar um significado especial" posteriormente, pois os aplicativos já podem usar esses caracteres.

Seria apenas uma grande mudança de última hora, como a que estamos fazendo com os nomes-chave agora.


Acho que precisamos distinguir duas coisas:

  1. Caracteres que têm um significado especial para keySetName (ou mais especificamente elektraKeyNameCanonicalize e elektraKeyNameUnescape ).
  2. Caracteres que têm um significado especial para um plugin, biblioteca ou outra parte do Elektra não preocupada com a manipulação de nomes de teclas.

O primeiro grupo será algum tipo de caractere reservado, cujo uso impróprio resultará em keySetName falha (e keyNew retornará NULL ). É aqui que o escape com uma barra invertida ajuda, pois a barra invertida diz a keySetName para interpretar o caractere a seguir literalmente e ignorar qualquer significado que ele possa ter.

O segundo grupo é totalmente diferente. Não há nada que possamos fazer durante keySetName (ou keyAddName , keyAddBaseName , etc.) para alterar se um caractere deste grupo tem um significado especial para algum plugin ou não. É inteiramente responsabilidade do plug-in decidir que e qualquer forma de escape do plug-in pode permitir evitar que o significado especial seja incluído no plug-in. Tenha em mente que dissemos que keySetName falha e keyNew retorna NULL para nomes inválidos. Em keySetName
não podemos, por exemplo, dizer que /# tem um significado especial, /#a não é permitido, mas /\# não tem nenhum significado especial e /\#a é permitido. Não temos ideia de como isso será usado. Se não permitirmos algumas chaves, nenhum plugin poderá usá-las. (Observação: no parágrafo acima: plugin = plugin, biblioteca, aplicativo, etc.)


Se você realmente deseja unificar quando algo pode ter um significado especial para um plugin / biblioteca, só consigo ver algo assim funcionando:

Defina algumas regras de escape para % , . , / e \ , como o efeito keySetName . Faça o índice de array de # 2698. As partes do nome da chave (com e sem escape) começando com @ devem estar no formato (regex) @[^@]+@.+ . O caractere @ não pode aparecer em nenhum outro contexto. Todo o resto não tem nenhum significado especial durante keySetName e pode ser usado irrestritamente. Plugins, bibliotecas, etc. NÃO PODEM atribuir significado especial a qualquer caractere individual ou a uma parte do nome da chave, exceto, às partes do nome da chave sem escape que começam com @ . Uma parte do nome de chave sem escape do formulário (regex) @[^@]+@.+ só pode ter um significado especial para o plug-in nomeado pela parte [^@] do regex. O que esse significado é, é com o plugin e determinado pela parte após o segundo @ .

Eu reconheço que isso é totalmente diferente da abordagem atual e totalmente irracional de implementar, se quisermos lançar 1.0 em breve, mas é a única abordagem de trabalho que posso ver, que nos permite dizer definitivamente se uma parte importante tem algum significado especial ou não.

Acho que precisamos distinguir duas coisas:

Minha esperança era que pudéssemos descartar essa distinção para tornar mais fácil entender a fuga como um todo. Então keyAddBaseName nunca adiciona algo que tenha um significado para Elektra.

Se isso não for possível, o requisito mínimo é que seja possível passar qualquer string para keyAddBaseName e receber de volta a mesma string ao solicitar o nome de base com keyBaseName , consulte # 2698.

Sim, quebraria algumas ocorrências de keyAddBaseName onde nomes de array foram adicionados. Mas vai quebrar alguns casos de qualquer maneira, já que nem todo nome de array é válido, então precisamos quebrar algum código:

  1. o código que assumiu que cada string pode ser definido ou
  2. o código que assumiu os arrays pode ser adicionado.

É muito claro para mim que não devemos quebrar 1., código ou seja, que assumiu cada corda pode ser passado para keyAddBaseName . "2." não é tão importante, essas são algumas ocorrências que podem ser corrigidas.

Outro exemplo próximo ao SSID: as entradas fstab podem ter basicamente tudo, incluindo /. Ou os nomes dos pontos de montagem no Elektra.

Então keyAddBaseName nunca adiciona algo que tenha um significado para Elektra.

Vejo agora que isso mais uma vez é o grande problema no coração da Elektra. Tudo deve ser um sistema coerente e bem definido, mas ao mesmo tempo tudo deve ser flexível e os plugins devem ser usados ​​tanto quanto possível. Isso simplesmente não pode funcionar.

O problema especificamente é a frase "significando para Elektra". Podemos garantir que keyAddBaseName nunca adiciona algo que tenha significado para elektra-core , ou em termos mais claros, que keyAddBaseName adiciona seu argumento como uma nova parte do nome de chave sem escape. Mas, para uma aplicação, "Elektra" também significa qualquer plugin da Elektra. Nessa interpretação, torna-se muito difícil evitar que keyAddBaseName adicione algo "com significado". Qualquer plugin pode decidir atribuir significado a qualquer nome de chave sem escape em qualquer ponto. Como eu disse, a única solução é introduzir um sistema muito restritivo, como aquele com @ proposto acima. Se você vier com algo diferente, me avise, mas para tudo que eu inventei até saber, encontrei um problema.

É muito claro para mim que não devemos quebrar 1., ou seja, o código que assumiu que cada string pode ser passada para keyAddBaseName

Por quê? Está quase claro para mim, por que isso é preferível? Nomes de arquivos UNIX, por exemplo, não podem conter / e ninguém jamais pensou que isso fosse um problema. (Não permitir / torna a divisão dos caminhos do UNIX em partes muito mais simples do que com nomes de chave).

Já estamos quebrando (quase) TODAS as partes do código que fazem interface com o Elektra adicionando : após o namespace. No estado atual das coisas, apenas as chaves em cascata sem nenhuma parte do array e também excluindo algumas outras coisas de caracteres especiais continuarão a funcionar sem exigir alterações. A compatibilidade com versões anteriores está longe da janela.

"2." não é tão importante, essas são algumas ocorrências que podem ser corrigidas.

Eu não teria tanta certeza disso. Na verdade, eu conheço apenas uma parte do Elektra que realmente assume que keyAddBaseName escapa de tudo e isso é elektra-kdb e as ferramentas que criam pontos de montagem.

As entradas do fstab podem ter basicamente tudo, incluindo /

Não sabe por que isso é relevante?

Ou os nomes dos pontos de montagem no Elektra.

Para criar o ponto de montagem user:/my/mount as ferramentas colocam a configuração do ponto de montagem em system:/elektra/mountpoints/user:\/my\/mount , mas podem usar qualquer outra chave exclusiva diretamente abaixo de system:/elektra/mountpoints , porque o ponto de montagem real é o valor de, por exemplo, system:/elektra/mountpoints/user:\/my\/mount/mountpoint . AFAICT system:/elektra/mountpoints pode ser um array. Não encontrei nenhum lugar que chame keyBaseName em uma chave diretamente abaixo de system:/elektra/mountpoints .

Pode haver algum lugar que usa mountGetMountpoint ou mountGetBackend para obter o ponto de montagem e reconstruir system:/elektra/mountpoints/user:\/my\/mount/ para acessar parte da configuração, mas isso pode ser facilmente resolvido adicionando o system:/elektra/mountpoints chave abaixo da qual a configuração é armazenada como um campo para struct _Backend .


Resumidamente:

o requisito mínimo é que seja possível passar qualquer string para keyAddBaseName e receber de volta a mesma string ao solicitar o nome de base com keyBaseName

Isso é facil. Mas combiná-lo com " keyAddBaseName aceitará todas as strings" é muito difícil ou quase impossível.

Vejo agora que isso mais uma vez é o grande problema no coração da Elektra. Tudo deve ser um sistema coerente e bem definido, mas ao mesmo tempo tudo deve ser flexível e os plugins devem ser usados ​​tanto quanto possível. Isso simplesmente não pode funcionar.

Sim, mas eu não diria que é um problema, mas um desafio. Queremos o melhor Elektra possível e, claro, às vezes ocorrem objetivos contraditórios.

Como eu disse, a única solução é introduzir um sistema muito restritivo, como aquele com @ proposto acima.

Sim, também vejo que não será possível ter tudo. Com o escape de matriz, já estamos bastante limitados a um escape de prefixo, ou seja, não podemos escapar outros caracteres dentro dos nomes de base.

Mas esse prefixo escapando pode ser o suficiente. E isso deve ser extensível a todos os personagens propostos acima. A limitação seria que toda a parte do nome da chave é escapada ou nada.

É claro que o escape não seria mágico, mas os aplicativos precisariam verificar se o significado de keyBaseName foi retirado ou fornecemos um keyUnescapedBaseName diferente para que os usuários da API possam ter a string com ou sem prefixo de escape.

Por quê? Está quase claro para mim, por que isso é preferível? Nomes de arquivos UNIX, por exemplo, não podem conter / e ninguém nunca pensou que isso fosse um problema. (Não permitir / torna a divisão de caminhos do UNIX em partes muito mais simples do que com nomes de chave).

É um problema para todos que implementam um navegador de arquivos. Alguns aplicativos tinham técnicas de codificação de URL para obter / entrar nos nomes dos arquivos. A "solução" mais moderna é usar o caractere Unicode 'DIVISION SLASH' (U + 2215) para barras.

Além disso, tenha em mente que todo o motivo da existência do Elektra é que a semântica do sistema de arquivos UNIX não é adequada para configuração. Na configuração, sequências arbitrárias para nomes de partes principais incluindo / são comumente usadas e, portanto, devem ser suportadas. Por exemplo, em YAML / são permitidos caracteres nas partes do nome da chave e também no TOML há "Chaves entre aspas".

Já estamos quebrando (quase) TODAS as partes do código que fazem interface com o Elektra adicionando o: após o namespace. No estado atual das coisas, apenas as chaves em cascata sem nenhuma parte do array e também excluindo algumas outras coisas de caracteres especiais continuarão a funcionar sem exigir alterações. A compatibilidade com versões anteriores está longe da janela.

Sim, e estou extremamente grato por você estar fazendo isso. Eu não teria sido capaz de fazer isso sozinho.

Eu não teria tanta certeza disso. Na verdade, conheço apenas uma parte do Elektra que realmente assume que keyAddBaseName escapa de tudo e que é elektra-kdb e as ferramentas que criam pontos de montagem.

Outra parte são os SSIDs. Este não foi um exemplo sintético, mas a Broadcom o implementou em seus dispositivos bluetooth. Portanto, eles contam com a possibilidade de adicionar qualquer nome de base.

Isso é facil. Mas combiná-lo com "keyAddBaseName deve aceitar todas as strings" é muito difícil ou quase impossível.

Sim, muito difícil, mas também um recurso exclusivo muito bom que nem mesmo o UNIX tinha antes. Podemos nos orgulhar disso.

Por exemplo, em YAML / são permitidos caracteres nas partes do nome da chave e também no TOML há "Chaves entre aspas".

Isso é realmente o que eu pensei que poderíamos apresentar, veja abaixo.


Acho que tudo isso pode ser resolvido introduzindo algo semelhante a "chaves entre aspas". Vou chamá-los de _partes-chave literais_.

Se uma parte-chave começa com @ (pode ser outro caractere, é claro), a parte-chave a seguir é uma _parte-chave literal_. Uma _parte de chave literal_ pode conter QUALQUER sequência de bytes incluindo zero bytes.

Sua forma sem escape é a seguinte:

  • Uma _parte de tecla literal_ começa com um caractere @ .
  • Outros @ caracteres são codificados como @@ .
  • Bytes zero são codificados como @0 .
  • @ não pode ocorrer de outra forma.
  • Como sempre, um byte zero termina a parte chave.

A forma de escape é um pouco diferente, para permitir uma impressão mais fácil:

  • Uma _parte de tecla literal_ começa com um caractere @ .
  • A _parte da chave literal_ NÃO é encerrada por um / . Apenas outro @ seguido por / ou um byte zero (fim da string), termina a parte da tecla _literal.
  • Qualquer byte pode ser codificado como @XX@ , onde XX é a forma hexadecimal do byte. Portanto, @ caracteres devem ser codificados como @40@ .

Agora keySetBaseName e keyAddBaseName aceitam QUALQUER parte válida da chave sem escape como argumentos. Eles definem / adicionam seu argumento não modificado como a última parte do nome da chave sem escape. Portanto, keyBaseName retornará o mesmo argumento. Além disso, keySetBaseName e keyAddBaseName transformam a parte sem escape em sua forma com escape e defina / adicione-a como a última parte do nome com escape.

Para resolver o problema de "queremos adicionar qualquer coisa como uma parte fundamental", apresentamos:

size_t keySetLiteralBaseName (Key * key, char * bytes, size_t size);
size_t keyAddLiteralBaseName (Key * key, char * bytes, size_t size);

Essas funções aceitam QUALQUER seqüência de bytes como seu argumento bytes . Eles então transformam o argumento em uma _parte chave literal_ não codificada prefixando-o com @ , substituindo outro @ por @@ e zero bytes por @0 . Isso é então passado para keySetBaseName ou keyAddBaseName .

Para tornar a decodificação _parte da chave literal_ mais fácil, também poderíamos adicionar funções de decodificação à API pública.

Eu gosto muito mais disso, porque deixa bem claro quando o usuário pretende adicionar coisas arbitrárias ao nome da chave e quando este não é o caso.

keySet / AddLiteralBaseName é uma proposta para adicionar um novo recurso. Atualmente, não temos uma maneira de codificar bytes nulos em nomes de chave. Quando alguém precisar disso, podemos voltar à sua proposta.

Por enquanto, no entanto, precisamos de uma boa semântica para keyAdd / SetBaseName. Conforme descrito por muito tempo, idealmente deve ser qualquer string, caso contrário, muitos plug-ins e aplicativos terão bugs porque eles não esperam que algumas strings não funcionem. #_10 é uma parte do nome da chave válida, ela pode ser usada como parte do nome da chave em basicamente todos os plug-ins ou aplicativos de armazenamento, não podemos discutir sobre isso. Definitivamente, não é uma boa ideia deixar um plug-in de armazenamento falhar porque ele encontrou #_10 algum lugar como parte do nome da chave durante a análise. E também não é uma boa ideia exigir que eles usem uma API diferente com um argumento de tamanho se eles não tiverem bytes nulos de qualquer maneira. Na verdade, que casos como #_10 ou / não precisam de tratamento especial é a razão para a existência de keyAdd / SetBaseName.

Por falar nisso. talvez seja melhor nos encontrarmos, por exemplo, na terça-feira?

Atualmente, não temos uma maneira de codificar bytes nulos em nomes de chave. Quando alguém precisar disso, podemos voltar à sua proposta.

Este é o ponto menos importante da proposta. Ele permite apenas zero bytes, porque não vejo razão para não permitir.

De qualquer forma, já existe um caso de uso:

Outra parte são os SSIDs. Este não foi um exemplo sintético, mas a Broadcom o implementou em seus dispositivos bluetooth. Portanto, eles contam com a possibilidade de adicionar qualquer nome de base.

Além do fato de que os SSIDs não têm nada a ver com bluetooth, o EEE 802.11 define claramente um SSID como qualquer sequência de bytes de até 32 bytes. Portanto, ou a Broadcom já faz algum pré-processamento para lidar com zero bytes ou seu código já está cheio de erros. Em qualquer caso, este é claramente um caso de uso para codificação de zero bytes em nomes de base de chave.


Em qualquer caso, não tenho ideia sobre possíveis extensões futuras para o conjunto de caracteres especiais, mas para o conjunto atual, acho que a solução implementada em # 3115 pode funcionar como está.

Se tentarmos o cenário de https://github.com/ElektraInitiative/libelektra/issues/2698#issuecomment -554680422 nesta versão, acontece o seguinte:

Chamar keyAddBaseName (key, "#_10") resulta na última parte de key->key e de key->ukey sendo #_10 . Por quê? Porque #_10 é um elemento válido da matriz. Sim, se #_10 fosse um SSID, não o veríamos como um elemento de array, mas girar com # corresponderia a ele, mas isso realmente importa?

Se pegarmos um elemento de array inválido como #10 ou #abc , keyAddBaseName escapará e a última parte do nome sem escape será #10 ou #abc , enquanto a última parte do nome com escape será \#10 ou \#abc .

Ainda não pensei sobre as regras teóricas de que precisamos para fazer este trabalho para extensões futuras, mas por enquanto acho que podemos deixar assim. Seria bom ter elementos de array sem o caractere inicial, mas isso realmente importa? Plug-ins de armazenamento são livres para codificar matrizes de maneira diferente, se eles tiverem um problema com o caractere # e para a linha de comando, devemos apenas adicionar kdb array* comandos que usam parâmetros inteiros normais, por exemplo, kdb arrayset /my/array 10 a .


Por falar nisso. talvez seja melhor nos encontrarmos, por exemplo, na terça-feira?

Terça-feira é ruim para mim ... Vou mandar um email para você.

Além do fato de que os SSIDs não têm nada a ver com bluetooth,

Eu quis dizer dispositivos Blueray (que têm capacidade wi-fi).

O EEE 802.11 define claramente um SSID como qualquer sequência de bytes de até 32 bytes de comprimento. Portanto, ou a Broadcom já faz algum pré-processamento para lidar com zero bytes ou seu código já está cheio de erros. Em qualquer caso, este é claramente um caso de uso para codificação de zero bytes em nomes de base de chave.

Sim você está certo. Mas é um novo recurso. Qualquer string em keySetBaseName não é um novo recurso.

Porque # _10 é um elemento de array válido. Sim, se # _10 fosse um SSID, não o veríamos como um elemento de array, mas globbing com # corresponderia, mas isso realmente importa?

Não, isso não importa.

Seria bom ter elementos de array sem o caractere inicial, mas isso realmente importa?

Não, o mais importante é que qualquer string pode ser alimentada para keySetBaseName, e keyBaseName retorna o que foi alimentado antes. Com a necessidade de iniciar caracteres em matrizes, posso definitivamente (e felizmente) viver.

[...] e para a linha de comando, devemos apenas adicionar comandos kdb array * que usam parâmetros inteiros normais, por exemplo, kdb arrayset / my / array 10 a.

Parece um bom plano.

Depois de reexaminar tudo, acho que há apenas um conflito. As seguintes declarações não podem ser unificadas.

  1. Uma parte da chave sem escape pode conter qualquer byte diferente de zero.
  2. Uma substring de uma parte da chave sem escape pode determinar uma propriedade da parte da chave sem escape.

Em nosso caso particular. A primeira declaração segue das garantias para keyBaseName et al. junto com o fato de você não querer que keyAddBaseName rejeite um argumento. Além disso, a proposta "partes-chave não gravadas começando com # são sempre índices de matriz" é um caso especial de 2.

Isso significa essencialmente manter 1, o que queremos, torna-se necessário sempre verificar novamente uma parte da chave sem escape completa, se você quiser testar uma determinada propriedade. Em particular, você deve verificar toda a parte da chave sem escape para saber se é um índice de array. Acho esta situação lamentável, mas parece inevitável.

Isso também significa que ainda podemos fazer toda a coisa de "partes da chave de escape consistindo inteiramente de dígitos são índices de array". O efeito colateral seria que no exemplo de SSID keyAddBaseName (key, "#_10") resultaria em um nome de escape terminando em /10 vez de /#_10 . Mas como você já aceitou o fato de que keyAddBaseName (key, "#abc") produz um nome de escape que termina em /\#abc , presumo que isso também não seja um problema.
Implementar isso seria uma tarefa maior, então seria um PR de acompanhamento para # 3115. Eu precisaria verificar se tudo que funciona com índices de array realmente usa o nome sem escape, além de atualizar tudo que cria chaves com partes de array.

Na verdade, 2. não é necessariamente necessário. Também podemos armazenar uma terceira string que contém o nome de base a ser retornado (talvez somente quando for realmente necessário para não desperdiçar muita memória).

Implementar isso seria uma tarefa maior

Isso não é bom, nós também precisamos de alguma forma acabar com isso. Talvez a 3ª string nos resgate, podemos otimizar isso mais tarde (se for necessário).

Fazemos uma lista completa de requisitos priorizados em uma decisão ou atendemos? A decisão será útil de qualquer maneira para que as pessoas mais tarde entendam por que fizemos assim e quais requisitos sacrificamos por outros requisitos.

Na verdade, 2. não é necessariamente necessário.

Como eu disse, foi uma proposta. Seria bom ter, mas infelizmente não funciona.

Também podemos armazenar uma terceira string que contém o nome de base a ser retornado (talvez somente quando for realmente necessário para não desperdiçar muita memória).

Precisaríamos armazenar uma 3ª versão inteira do nome da chave, caso contrário keySetBaseName (key, NULL) funcionaria corretamente.

No momento, não há muitas propriedades que uma peça-chave possa ter. Pelo menos não as propriedades que são interessantes em toda a Elektra. "É uma parte do índice do array?" é na verdade o único em que consigo pensar. Se, no futuro, tivermos mais propriedades (por exemplo, se adicionarmos o conceito de "marcadores contextuais" ao núcleo), podemos pensar em otimizações.

Isso não é bom, nós também precisamos de alguma forma acabar com isso.

Eu sei, é exatamente por isso que eu disse que não farei no # 3115. Se decidirmos que precisamos, abrirei outro PR. Este segundo PR vai dar muito trabalho e será uma mudança radical. No entanto, deve ser uma alteração de interrupção muito menor e (a maioria) outros PRs simultâneos não devem ser afetados tanto quanto serão quando fundimos o # 3115.

Fazemos uma lista completa de requisitos priorizados em uma decisão ou atendemos?

Escreverei a documentação, incluindo uma decisão, quando o código de # 3115 estiver pronto. As questões em aberto agora são:

  1. Além de / e \ , quais caracteres podem ter um significado especial no início de uma parte chave?
    Em # 3115, eles são atualmente # , % , . e @ .
  2. Qual é o significado especial? Isso pode ser diferente dependendo do resto da parte-chave.
    Em # 3115, temos o seguinte:

    • # significa parte do array, se o resto da parte da chave for apenas dígitos ou primeiro n sublinhados e então n + 1 dígitos ( n >= 0 ) e nada mais. Uma parte de apenas # não tem nenhum significado especial em geral (pode significar agrupamento de array para algumas partes de Elektra). Qualquer outra parte começando com # significa que o nome da chave é inválido.

    • % significa parte vazia se a parte for apenas % . Qualquer outra parte começando com % significa que o nome da chave é inválido.

    • . tem significado especial apenas se a parte for apenas . ou exatamente .. . Todas as outras partes começando com . atualmente não têm nenhum significado especial, ou seja, o nome da chave não é inválido. (Anteriormente, uma parte começando com . tornava uma chave inativa)

    • @ está reservado. Qualquer parte começando com @ significa que o nome da chave é inválido.

  3. O escape dos caracteres especiais de 1 deve sempre ser permitido ou apenas quando necessário?
    Em # 3115, o escape é sempre permitido.
  4. Queremos que as partes principais consistindo inteiramente de dígitos sejam interpretadas como partes do array? Em caso afirmativo, qual é a representação canônica? Apenas dígitos também, começando com # depois apenas dígitos ou o mesmo que a versão sem escape, ou seja, # e sublinhados?
    Em # 3115, sempre exigimos que as partes do array comecem com # e sua representação canônica é a mesma que a sem escape.

Minhas respostas sugeridas são:

  1. # , % , . , @ , $ , & e ? devem ser o suficiente para possíveis usos futuros. Em particular, acho que não devemos reservar _ que só causará problemas.
  2. Como temos em # 3115. $ , & e ? são reservados para uso futuro como @ .
  3. Sempre permitido.
  4. Pessoalmente, sou contra isso. Ter o caractere inicial torna mais fácil localizar as partes do array ao observar os nomes das chaves. Como sugerido em # 2698, qualquer conflito com caracteres especiais em formatos de armazenamento deve ser resolvido por plug-ins de armazenamento, não pelo núcleo, e a ferramenta kdb deve ter apenas comandos especiais de array.

Coisa um pouco não relacionada: pode ser possível transformar directoryvalue em uma biblioteca (ou mesmo torná-la parte do núcleo) e dar a ela uma interface privada que permite a criação de chaves que não seriam possíveis por meio da API pública. Então não teríamos que nos preocupar com colisões por causa do nome __directoryvalue . Um dos caracteres reservados seria usado para isso. Não pensei muito sobre isso, mas pode ser uma boa ideia, já que a maioria dos formatos de armazenamento são bons para legibilidade humana e não oferecem suporte a chaves com um valor e chaves abaixo.

Além de / e \, quais caracteres podem ter um significado especial no início de uma parte-chave?
Em # 3115, atualmente são #,%,. e @.

É disso que se trata basicamente este problema: coletar caracteres que potencialmente têm um significado especial (agora ou reservados).

O escape dos caracteres especiais de 1 deve sempre ser permitido ou apenas quando necessário?

Sim, sempre seja permitido.

Queremos que as partes principais consistindo inteiramente de dígitos sejam interpretadas como partes do array? Em caso afirmativo, qual é a representação canônica? Apenas dígitos também, começando com # e depois apenas dígitos ou o mesmo que a versão sem escape, ou seja, # e sublinhados?

Isso depende muito de quais propriedades de nomes de base perdemos. Da perspectiva do usuário, é "bom" se nenhum # for necessário; da perspectiva da API, é muito importante que keySet/AddBaseName simplesmente funcione.

Em particular, acho que não devemos reservar _ isso só vai causar problemas.

E para mudar o globbing para * ?

Ter o caractere inicial torna mais fácil localizar as partes do array ao observar os nomes das chaves.

Não acho que seja um grande problema: os números dentro de uma string também são muito fáceis de detectar:

user/here/is/a/test/1/not/a/number/4/here/is/a/number

Então não teríamos que nos preocupar com colisões por causa do nome __directoryvalue.

Se implementado corretamente, não precisamos nos preocupar também se implementado como plugin, o plugin pode escapar do valor __diretório já presente.

Meu sonho é que keySetBaseName escaparia de _directoryvalue (um sublinhado ou @ seria o suficiente), mas o plugin directoryvalue usaria keyAddName para obter um _directoryvalue bruto dentro do nome da chave. (Que seria protegido porque o sublinhado ou @ é um caractere reservado que não deve ser usado para aplicativos).

Espero que possamos discutir isso hoje, espero que assim possamos chegar mais facilmente à conclusão.

Isso depende muito de quais propriedades de nomes de base perdemos.

Como eu disse, não devemos perder nada em comparação com o estado atual de # 3115, mas também não necessariamente ganharemos muito. A questão principal é quanto trabalho queremos investir na mudança do nome da chave. Vamos falar sobre isso hoje.

E para mudar o globbing para * ?

* já tem significado para a biblioteca globbing. Significa qualquer parte importante. # corresponde apenas a partes do array e _ corresponde a partes que não sejam do array.

Não acho que seja um grande problema: os números dentro de uma string também são muito fáceis de detectar

Pode ser apenas eu, mas não localizei /1/ a princípio.

Se implementado corretamente, não precisamos nos preocupar também se implementado como plugin, o plugin pode escapar do valor __diretório já presente.

Veja # 3256 para uma solução alternativa usando metakeys.

Meu sonho é que keySetBaseName escapasse de _directoryvalue

Eu sou fortemente contra isso. O núcleo não deve se preocupar de forma alguma com o que os plug-ins fazem ou quais são os requisitos que eles possuem. Isso também abre um precedente ruim. E se outro plugin usar _averyspecialkey para algo? Vamos atualizar keySetBaseName sempre que isso acontecer?

Resultado da conversa:

  • as propriedades do nome de base já parecem estar mais ou menos como eram antes
  • arrays continuarão a começar com # (mas _ não será necessário)
  • os caracteres acima serão escapados se estiverem na primeira posição, exceto: #
  • keySetBaseName não será e não pode ser atualizado para novos caracteres, a lista acima (quando finalizada) é uma lista completa para Elektra 1.0

os caracteres acima serão escapados se estiverem na primeira posição, exceto: #

O comportamento atual (em # 3115) de keySetBaseName e keyAddBaseName é definido por esta função:

https://github.com/ElektraInitiative/libelektra/blob/9e91654ca72e6cd58b3b54892e78b5a5b2810214/src/libs/elektra/keyname.c#L1360 -L1462

Nós apenas escapamos quando é necessário evitar escapes desnecessários no nome escapado.

Além disso, como você perguntou, se há uma relação de 1: 1 entre o nome da chave com escape e sem escape:

Não, não há. Decidimos permitir escape desnecessário:

O escape dos caracteres especiais de 1 deve sempre ser permitido ou apenas quando necessário?

Sim, sempre seja permitido.

Isso significa que, por exemplo, /key/%abc e /key/\%abc são nomes de chave com escape diferentes para o mesmo nome de chave sem escape. Ou seja, aquele com namespace em cascata e as duas partes key e %abc .

Se quisermos garantir uma relação 1: 1, podemos dizer que o escape só é permitido quando necessário (não gosto disso) ou remover barras invertidas desnecessárias durante a etapa de canonização.
Em qualquer caso, a relação 1: 1 requer que keySetBaseName e keyAddBaseName se comportem como descrito acima, ou seja, ele deve saber quando é necessário escapar.

Pessoalmente, não acho que a relação 1: 1 seja necessária. Precisamos apenas de uma relação: 1 para fazer ksLookup funcionar. Normalmente não deve ser um problema, se procurarmos /key/\%abc e recebermos /key/%abc volta ou vice-versa.

Obrigado por investigar o comportamento de ida e volta. Sim, a pesquisa não é grande coisa (já é 1: n por causa da cascata), mas as chaves com nomes diferentes se removem ao anexá-las ao conjunto de chaves é feio. E, claro, o fato de não ser de ida e volta é outro objetivo importante: todo KeySet deve, após a serialização e serialização, ser exatamente o mesmo, e isso não seria dado se \% e % fossem "idênticos "na representação interna.

Você talvez tenha uma solução para o problema do ksAppend e do round tripping?

É uma questão de definição. O que identifica uma chave de maneira única?

A resposta técnica é o nome sem escape. É o que um KeySet usa para diferenciar as chaves.
Os usuários só precisam se acostumar a saber quando dois nomes de chave são iguais. É semelhante a perceber que as frações 2/3 e 4/6 são iguais.

Se você ainda deseja a relação 1: 1, o escape só deve ser permitido quando necessário. Isso não é mais difícil de implementar, mas pode ser irritante para os usuários.

É uma questão de definição. O que identifica uma chave de maneira única?

Até agora, dizer "o nome identifica uma chave" era suficiente porque havia 1: 1 entre com escape e sem escape. Eles só foram armazenados tanto para melhoria de desempenho. (espaço x tempo)

Eu preferiria que pudesse ficar assim.

Se você ainda deseja a relação 1: 1, o escape só deve ser permitido quando necessário. Isso não é mais difícil de implementar, mas pode ser irritante para os usuários.

Por que isso seria irritante?

Minha ideia de \#123 vs. #123 era que não é o mesmo nome de chave e não tem o mesmo significado (um significa o literal #123 , o outro é o 124º entrada da matriz). Ambos teriam nomes com e sem escape diferentes.

Se eles agora tiverem o mesmo nome sem escape, podemos simplesmente rejeitar keyAddName(k, "\\#123") . Não há benefício em tê-lo, ou há?

Minha ideia de \#123 vs. #123 era que não é o mesmo nome de chave e não tem o mesmo significado (um significa o literal #123 , o outro é o 124º entrada da matriz). Ambos teriam nomes com e sem escape diferentes.

Esse exemplo não demonstra nada. Obviamente \#123 e #123 têm diferentes versões sem escape, caso contrário não seria possível obter a parte sem escape #123 de qualquer forma.

Arrays também são um mau exemplo, porque dissemos que # deve introduzir uma parte válida do array ou ser escapado, para evitar erros fáceis. Em vez disso, vamos olhar para % .

Se a parte com escape for /%/ , obteremos uma parte sem escape vazia e se for /\%/ obteremos a parte sem escape % . Obviamente, ambos devem ser peças-chave com escape válidas. Até agora tudo bem.
A questão agora é sobre as partes /%abc/ e /\%abc/ . Ambos mapeiam para a parte sem escape %abc . Ambos são permitidos ou um deles é inválido? Se ambos forem permitidos, não temos uma relação 1: 1.

Isso é o que eu quis dizer com:

O escape dos caracteres especiais de 1 deve sempre ser permitido ou apenas quando necessário?

Ao que você respondeu:

Sim, sempre seja permitido.

Que interpretei como /%abc/ e /\%abc/ são permitidos. Percebo agora que você quis dizer "Sim, sempre obrigatório", ou seja, apenas /\%abc/ é válido.

De qualquer forma...
Temos duas opções aqui:

  1. Um caractere reservado deve apresentar uma parte válida com significado especial ou deve ser escapado.
    No exemplo acima, isso significa que apenas /\%abc/ é válido.
  2. Um caractere reservado deve ser escapado, quando a parte teria um significado especial sem o escape.
    No exemplo acima, isso significa que apenas /%abc/ é válido.

A escolha pode ser feita de forma independente para cada um dos personagens reservados. Apenas uma dessas opções pode ser escolhida por personagem para manter a relação 1: 1.


Em # 3115, é atualmente a opção 1 para # e a opção 2 para . e % . Para @ ambas as opções são iguais, sempre requer escape. Não há partes válidas começando com @ . Terei que verificar se tudo o resto está correto, mas acho que temos uma relação 1: 1 em # 3115 agora.

Obrigado pela explicação detalhada. Sim, não é tão importante que /%abc/ seja escapável com uma única barra invertida. A viagem de ida e volta é muito mais importante. Também podemos usar outra coisa para escapar disso (na camada acima).

Não há partes válidas começando com @.

Como funcionará quando atribuirmos um significado a @ ?

Terei que verificar se tudo o resto está correto, mas acho que temos uma relação 1: 1 em # 3115 agora.

Obrigado: 100:

Como funcionará quando atribuirmos um significado a @?

Você está certo, para garantir compatibilidade futura, temos que escolher a opção 1. É fácil de ver:
/\%abc/ , /%/ e /\%/ não são válidos, mas /%abc/ não são. Todas as partes começando com @ são inválidas agora, mas começando com \@ é permitido e ainda estará correto, se algumas partes começando com @ se tornarem válidas.

Excluí o conjunto de regras que postei antes, porque depois de brincar com uma gramática ANTLR, percebi que as regras não ajudam. Acho que ter uma relação 1: 1 E garantir a compatibilidade com versões anteriores ao dar significado aos caracteres reservados é basicamente impossível.

Vamos tomar @ como exemplo. Atualmente, apenas as partes começando com \@ são válidas, aquelas começando com @ são sempre inválidas. Partes do formulário \@XYZ ( XYZ é arbitrário) não têm escape em @XYZ .

Agora decidimos introduzir um significado para @ . Todas as partes do formulário @XYZ ( XYZ arbitrário) para o qual o predicado foo(XYZ) ( foo é algum predicado de string) é verdadeiro agora estão sem escape em bar(XYZ) ( bar é alguma função que mapeia strings para strings). Para manter a relação 1: 1, devemos obviamente garantir que nenhuma outra parte fique sem escape em bar(XYZ) . Mas isso significa que algumas chaves atualmente válidas se tornarão inválidas, porque atualmente é possível obter chaves com nomes arbitrários sem escape. Isso quebra a compatibilidade. (Observação: pode ser possível manter a relação 1: 1 e o comportamento de ida e volta frouxo entre as versões "sem significado para @ " e "significado para @ ", mas isso é apenas um mudança de quebra diferente.)

Posso ter uma solução para isso, mas já sei que você não vai gostar, pois envolve a proibição de certos nomes sem escape.

A explicação da minha solução ficou bastante longa, então coloquei em um arquivo em # 3115.

A ideia básica é:

  • Nem todas as sequências de bytes são mais nomes de chave sem escape. Algumas strings C não são mais partes de nomes de chave sem escape válidas.
  • Isso torna possível uma relação 1: 1 à prova de futuro de nomes de chave com e sem escape. Strings podem se tornar partes chaves sem escape válidas, mas uma vez que uma string é válida, ela não pode mais se tornar inválida.

A explicação detalhada e o que isso significa podem ser encontrados aqui . Você pode adicionar comentários aqui: https://github.com/ElektraInitiative/libelektra/commit/86d8e7806bfb92e95a7c519e09e95fa278eadb05

Muito obrigado por trabalhar nisso! @sanssecours, você pode dar uma olhada se também gostar da ideia?

Posso ter uma solução para isso, mas já sei que você não vai gostar, pois envolve a proibição de certos nomes sem escape.

Por falar nisso. não é que "eu não goste", é que ninguém vai gostar do Elektra se todos os plug-ins de armazenamento tiverem bugs porque eles não podem aceitar algumas strings.

têm bugs porque não podem aceitar algumas strings

Não é bugado, se definirmos dessa forma. JSON requer escape semelhante a strings C. Ninguém reclama disso. Qualquer plugin Elektra usando JSON exigiria apenas o uso de mais alguns escapes.

Embora deva ser visível nas definições mais detalhadas, talvez devesse ter declarado explicitamente que nenhuma funcionalidade real é perdida. É apenas um pouco mais complicado em alguns casos.

Para cada sequência de bytes, ainda há um único nome de chave sem escape que representa essa sequência de bytes. Acontece que a sequência original de bytes e o nome da chave sem escape que a representa não serão mais sempre os mesmos.

Não é bugado, se definirmos dessa forma. JSON requer escape semelhante a strings C. Ninguém reclama disso. Qualquer plugin Elektra usando JSON exigiria apenas o uso de mais alguns escapes.

Você está comparando maçãs com bananas aqui. JSON é um formato de serialização, estamos discutindo uma estrutura de dados aqui (KeySet). No nível de serialização, os plug-ins de armazenamento ainda precisam escapar / cancelar o escape de nomes e valores de chave para que os separadores possam ser distinguidos.

Embora deva ser visível nas definições mais detalhadas, talvez devesse ter declarado explicitamente que nenhuma funcionalidade real é perdida. É apenas um pouco mais complicado em alguns casos.

Sem API é difícil dizer o que significa "um pouco mais complicado".

Acontece que a sequência original de bytes e o nome da chave sem escape que a representa não serão mais sempre os mesmos.

Acho que poderíamos viver com isso.

Estou apenas preocupado que esta mudança seja muito grande (parece que também será necessária uma modificação em todo o plugin de armazenamento) e não seremos capazes de concluí-la. Talvez seja melhor esquecer a seleção natural que trouxe a maior parte desse problema?

Talvez seja melhor esquecer a seleção natural que trouxe a maior parte desse problema?

A classificação natural não tem nada a ver com isso. AFAIK, nem mesmo é mencionado em nenhuma parte da proposta. O problema é reverter caracteres para uso futuro, evitando alterações significativas.

Sem API é difícil dizer o que significa "um pouco mais complicado".

A API está na proposta. Neste caso, "um pouco mais complicado" significa apenas escolher entre duas operações ( pushL e pushU , nomes são marcadores de posição) em vez de usar sempre a mesma ( keyAddBaseName ). E às vezes ignorando uma barra invertida inicial ao comparar partes-chave com strings.

Estou apenas preocupado que essa mudança seja muito grande

É claro que é uma grande mudança, mas reduzirá futuras mudanças importantes.

não poderemos terminar

Bem, isso depende inteiramente do prazo ...

Conforme discutido, acho que devemos antes esquecer este assunto (reserva de caracteres especiais). Em vez disso, o escape de nível superior (como arrays # , % ) ou reserva de caracteres especiais ( @ ) deve ser feito diretamente nos plug-ins de armazenamento.

Bem, isso depende inteiramente do prazo ...

Se você quiser fazer uma tese de mestrado sobre bibliotecas de software preparadas para o futuro, você está livre para reabrir este tópico: wink:

Conforme discutido [...]

Não é disso que me lembro da discussão. Achei que tivéssemos concordado em terminar o nº 3115 e depois pensar sobre esse problema novamente.

Vou terminar o número 3115 e também acrescentarei alguns exemplos e explicações simples em inglês à proposta.

Em vez disso, o escape de nível superior (como matrizes #,%) ou reserva de caracteres especiais (@) deve ser feito diretamente nos plug-ins de armazenamento.

Francamente, esta é uma solução estúpida ...

Sempre que adicionarmos algo novo aos nomes das chaves, teremos que atualizar todos os plug-ins de armazenamento. Esse é exatamente o motivo que você usou contra a minha solução (que só requer isso uma vez).

Ele também não evita a atualização dos plug-ins agora, já que a AFAIK nenhum deles realmente lida com nomes de chave 100% corretos (partes do array).

Se você realmente não quer minha proposta, dê um motivo contra ela, em vez de propor uma solução que não resolve nada e exige quase o mesmo esforço.

Se você quiser fazer uma tese de mestrado sobre bibliotecas de software preparadas para o futuro

Não, não quero fazer isso ... Só quero tornar os nomes-chave da Electra à prova de futuro, o que é uma tarefa muito menor e mais simples.

Não é disso que me lembro da discussão. Achei que tivéssemos concordado em terminar o nº 3115 e depois pensar sobre esse problema novamente.

Sim, não terminamos a discussão, mas:

  • minha recomendação é corrigir outros bugs e problemas de usabilidade importantes.
  • Não posso e não vou proibir você de pensar nisso de qualquer maneira: wink:

Ele também não evita a atualização dos plug-ins agora, já que a AFAIK nenhum deles realmente lida com nomes de chave 100% corretos (partes do array).

Por favor, reporte os bugs. O uso de matrizes conforme especificado em doc / decision / array.md deve ser correto. Então #0 é um "nome simples sem significado" e os arrays só têm significado com uma chave diretamente abaixo que contém os metadados "array".

Se você realmente não quer minha proposta, por favor, dê uma razão contra ela,

Gosto muito da proposta. Mas coisas como # 1074 (e veja https://github.com/ElektraInitiative/libelektra/projects/9 para mais) são IMHO muito mais críticas para o sucesso da Elektra.

em vez de propor uma solução que não resolve nada e exige quase o mesmo esforço.

O que você quer dizer? Minha última proposta foi simplesmente não reservar caracteres e deixar que os plug-ins de armazenamento façam o que quiserem. Não vejo nenhum esforço em "implementar" esta proposta (é um NOP).

Não, não quero fazer isso ... Só quero tornar os nomes-chave da Electra à prova de futuro, o que é uma tarefa muito menor e mais simples.

Talvez isso já seja suficiente para uma tese de mestrado, se você terminar as provas. Não pesquisei nenhum trabalho relacionado, talvez outra pessoa já tenha feito algo assim.

O uso de matrizes conforme especificado em doc / decision / array.md deve ser correto.

Esse pode ser o caso, mas o tutorial para plug-ins de armazenamento discorda e até mostra que yamlcpp não funciona dessa forma.

Mas coisas como # 1074 são IMHO muito mais críticas para o sucesso da Elektra.

Estou preocupado com as mudanças nos nomes-chave, porque isso é o que já estou fazendo e tenho muitos insights agora. Além disso, já temos uma alteração significativa nos nomes das chaves, então não importa muito se quebrarmos mais coisas.

Os pontos de montagem user / dir seriam bons sim, mas não tenho ideia de como resolver isso. Provavelmente levaria tanto ou mais tempo para encontrar e implementar uma solução do que levaria para implementar minhas alterações propostas para nomes de chave.

Minha última proposta foi simplesmente não reservar personagens

Você mencionou reservar @ .

deixe que os plug-ins de armazenamento façam o que quiserem

Isso só leva a incompatibilidades. É claro que não podemos impedir que plug-ins de armazenamento usem um formato completamente diferente, mas não dar nenhuma orientação é apenas pedir problemas.

Esse pode ser o caso, mas o tutorial para plug-ins de armazenamento discorda e até mostra que yamlcpp não funciona dessa maneira.

@sanssecours, você pode dar uma olhada nisso? Se reconhecermos arrays apenas por causa da estrutura (nomes com #0 ), o KeySet não terá ponta arredondada.

Provavelmente levaria tanto tempo ou mais para encontrar e implementar uma solução

Sim, mas o ponto de montagem user / dir é algo com que todo usuário Elektra é freqüentemente confrontado. Se algum dia precisarmos de caracteres reservados, não sabemos.

Você mencionou reservar @.

Sim, os plug-ins de armazenamento podem reservar e escapar do que quiserem.

Isso só leva a incompatibilidades. É claro que não podemos impedir que plug-ins de armazenamento usem um formato completamente diferente, mas não dar nenhuma orientação é apenas pedir problemas.

Eu concordo plenamente. Talvez algumas pessoas em alguns anos irão nos odiar por não termos reservado alguns personagens (mas talvez também não). Mas tenho certeza de que não contribuirá para o sucesso do Elektra 1.0. Para ser claro: não sou totalmente contra a implementação, mas outras coisas (https://github.com/ElektraInitiative/libelektra/projects/9) são IMHO muito mais altos na lista de prioridades. Você é livre para discordar e implementá-lo de qualquer maneira. Eu não rejeitaria o PR, desde que não seja muito complicado para plug-ins de armazenamento (e todos os plug-ins sejam corrigidos). Mas há um alto risco de que outras coisas (que são essenciais para o sucesso) não sejam implementadas e o Elektra não seja usado em projetos importantes como o KDE.

@sanssecours, você pode dar uma olhada nisso? Se reconhecermos arrays apenas por causa da estrutura (nomes com #0 ), o KeySet não terá ponta arredondada.

Atualizei o comportamento do YAML CPP e o plugin Directory Value no PR 3357. A solicitação pull também atualiza parte da documentação para levar em consideração os metadados array obrigatórios.

Já atualizei a proposta em # 3447. Espero que agora seja mais fácil de entender (ainda é muito longo).

https://github.com/kodebach/libelektra/blob/dcec6e865bba32f6d83c40c2f711c2e70dde6d62/doc/proposals/keynames.md

@ markus2330 Vou colocar isso aqui, embora a discussão anterior tenha sido em # 3223, porque acho que se encaixa melhor.

Acabei de descobrir / lembrar que na versão atual do Elektra [1], já é o caso (e implementado dessa forma) que "qualquer parte do Nome da chave ESCAPADA que comece com @ torna toda a chave inválida". Isso significa que poderíamos - sem implementar nenhuma das outras alterações da proposta - usar nomes de campo começando com @ para finalidades especiais em plug-ins de armazenamento, como a proposta sugere com $meta e $value .

@ bauhaus93 Isso pode ajudá-lo quando você implementa e metadados em toml (e também para chaves de valor não-folha, até certo ponto).

Para quem não leu a proposta, a ideia seria essencialmente (para JSON):

{
   "key": {
        "@value": "127.0.0.1",
        "sub": "xyz",
        "@meta": {
            "check/ipaddr": "ipv4"
      }
}

Transforma-se em duas chaves:

key = 127.0.0.1
key/sub = xyz

e key também tem estes metadados:

check/ipaddr = ipv4

~ Como key/@value e key/@meta são nomes de chave reservados (ou mesmo inválidos em # 3447), isso não pode causar conflitos. ~


[1] master apenas menciona isso na documentação , mas permite que você crie tais Chaves. # 3447 por outro lado ~ proíbe totalmente essas chaves ~ requer que @ tenha escape no início das partes do nome da chave em nomes de chave com escape. A documentação também tem uma cláusula semelhante para _ , mas isso também não é aplicado em # 3447.

Desculpem a confusão, mas tive que esclarecer partes do comentário acima. A parte sobre @ só se aplica ao nome da chave com escape. O nome sem escape (como uma string C) "\01\00key\00@meta\00" ainda é válido em # 3447, como sempre foi. Isso significa que @meta não pode ser usado para metadados sem outras considerações no plug-in de armazenamento.

No entanto, como sempre foi um nome reservado e exigiremos o escape em # 3447, acho que ainda é justo usá-lo em um plugin de armazenamento. OMI, um usuário não deve esperar que um nome reservado sempre possa ser usado sem problemas. Mas é claro que precisaremos tomar alguns cuidados. Uma possibilidade seria esta (JSON novamente):

{
   "key": {
        "@value": "127.0.0.1",
        "@sub": "xyz",
        "@meta": {
            "check/ipaddr": "ipv4"
      }
}

Transforma-se em duas chaves (observe o \ para escape):

key = 127.0.0.1
key/\<strong i="15">@sub</strong> = xyz

Mas isso

{
   "key": {
        "@@value": "127.0.0.1",
        "@@sub": "xyz",
        "@@@sub": "abc",
        "@@meta": {
            "check/ipaddr": "ipv4"
      }
}

Transforma-se em (novamente \ para escapar):

key/\<strong i="23">@value</strong> = 127.0.0.1
key/\<strong i="24">@sub</strong> = xyz
key/\@<strong i="25">@sub</strong> = abc
key/\@meta/check\/ipaddr = ipv4

As regras aqui seriam:

  • o nome do campo não começa com @ -> use o nome do campo e adicione keyAddBaseName
  • o nome do campo começa com mais de um @ -> remova um primeiro @ e use o restante para keyAddBaseName
  • o nome do campo começa com um único @ -> verifique se o nome do campo tem um significado especial (por exemplo, @value ou @meta ):

    • se tiver um significado especial, processe de acordo

    • caso contrário, use o nome do campo para keyAddBaseName (por exemplo, @sub )

(Observação: keyAddBaseName pega um nome sem escape e faz o escape necessário para manter o nome da chave válido)

Não entendi o objetivo dos dois últimos comentários. Esta é uma proposta sobre a substituição do plugin directoryvalue?

(observe o \ para escapar)

Para @ normalmente usamos @ para escapar, então simplesmente descartar o primeiro @ se houver vários. Seria bom se isso também estivesse documentado na descrição do nome da chave. Poderíamos mudar para \ (se isso tornar o escape para nomes de chave em geral mais fácil de entender), mas isso precisa de mudanças pelo menos no plugin base64. (plug-in nulo é excluído em # 3491)

Não entendi o objetivo dos dois últimos comentários. Esta é uma proposta sobre a substituição do plugin directoryvalue?

A parte @value é sim. Mas é mais geral. @meta pode ser usado para armazenar metadados dentro de um formato com uma única estrutura de objeto aninhado, como JSON ou TOML (ainda não tenho certeza sobre YAML, por causa das tags).
Basicamente, como tudo no arquivo JSON se refere a alguma chave em algum lugar, simplesmente não há lugar para armazenar metadados. A menos que imponha algumas limitações à estrutura do arquivo JSON, provavelmente você não pode simplesmente montar algum arquivo de configuração. [1]

Como eu disse, você precisa impor restrições para ajustar metadados em JSON (AFAIK, o mesmo vale para TOML). Portanto, sim, minha proposta nos comentários acima impõe uma restrição aos arquivos JSON, mas os aplicativos que usam @ no início de um campo JSON são provavelmente muito raros.

Para @, normalmente usamos @ para escapar, então simplesmente descartar o primeiro @ se houver vários. Seria bom se isso também estivesse documentado na descrição do nome da chave. Poderíamos mudar para \ (se isso tornar o escape para nomes de chave em geral mais fácil de entender), mas isso precisa de mudanças pelo menos no plugin base64.

Não tenho certeza de como o plugin base64 é relevante aqui, mas gostaria de ser muito claro:

No atual master (6a1535c094c7be2f441bd0e7b0dda1c50e97ee1d) keyNew ("/elektra/@abc", KEY_END) funciona e cria um nome sem escape com as partes elektra e @abc .
Em # 3447 keyNew ("/elektra/@abc", KEY_END) retorna NULL porque o nome é considerado inválido, mas keyNew ("/elektra/\@abc", KEY_END) funciona e cria um nome sem escape com as partes elektra e @abc .
Não tenho certeza do que keyNew ("/elektra/\@abc", KEY_END) faz no master.

keyAddBaseName (k, "@abc") funciona em ambos os casos, a única diferença é o nome de escape que ele cria.

Eu também não me lembro por que fiz essa alteração. Provavelmente houve uma boa razão, mas em todo caso está feito agora e não acho que voltar a ser fácil.


[1] Como sempre, o problema aqui é que a Elektra quer fazer tudo e agradar a todos. Por um lado, queremos permitir plug-ins de armazenamento que possam ler arquivos arbitrários em um formato padrão (por exemplo, JSON) e transformá-los em KeySets. Por outro lado, queremos permitir que os aplicativos usem strings arbitrárias como parte de um nome de chave. Isso pode funcionar por algum tempo, mas pelo menos quando você chega aos metadados, ele quebra para certos formatos.

JSON é uma árvore única com valores apenas nos nós folha. KeySets são uma árvore com valores em cada nó, e alguns dos nós também possuem um link para uma árvore separada inteira. Você pode ser capaz de converter entre os dois, mas um deles deve impor limitações ao outro para ter uma conversão sem perdas.

Como eu disse, você precisa impor restrições para ajustar os metadados

@kodebach isso significa que você é a favor de restringir os formatos em que os metadados podem ser armazenados?

Nunca me deparei com isso, porque geralmente usei dump e mmapstorage e apenas raramente importei / exportei configurações usando outros plug-ins. Isso é muito lamentável. Como um usuário, eu preferiria ser capaz de importar / exportar para especificações padrão (perdendo metadados) enquanto armazeno os dados reais (incluindo metadados) usando um formato interno elektra arbitrário.

Acho que restringir o formato pode ser confuso para os usuários. Por exemplo, se a Elektra fornece um plugin JSON não experimental, então eu esperaria que ele fosse capaz de lidar com entradas arbitrárias em conformidade com as especificações. Não está claro para mim como o usuário seria capaz de verificar se seus arquivos de configuração estão de acordo com a especificação restrita.

@ markus2330 o que você acha sobre a imposição de restrições ao formato?

EDIT: Concordo que "Elektra quer fazer tudo e agradar a todos" é um problema.

isso significa que você é a favor de restringir os formatos que os metadados podem ser armazenados?

Precisamos definir nossas prioridades. O que exatamente é uma necessidade absoluta e onde as coisas podem mudar. Como está agora, a única maneira para muitos formatos é armazenar metadados nos comentários ( @ bauhaus93 fez isso em # 3500 para TOML). IMO, esta não é uma solução, mas apenas uma solução alternativa desajeitada. A pior parte é que abusa daquela parte que nunca deve ser tocada por um analisador e pode afetar drasticamente a legibilidade de um arquivo de armazenamento. Alguns formatos (nomeadamente JSON) também não têm comentários.

Restrições muito básicas que poderíamos impor (usando JSON como exemplo novamente) seriam que todos os arquivos devem ter a seguinte aparência:

{
    "kdb": {
       "elektra": {
          "version": 1
        }
    },
    "meta": {
       "elektra/version": {
           "type": "long"
       }
    }
}

Outras "restrições" incluem a interpretação de certos nomes de chave como @meta maneiras especiais e fornecer métodos de escape.

O objeto kdb contém as chaves reais e meta contém os metadados. (Observação: para resolver chaves não-folha com valores, você precisa de outro objeto)

Em vez de dois objetos JSON, também podemos usar arquivos separados. Mas isso precisaria do suporte de pelo menos o resolvedor e talvez até mesmo do código / plugin de backend. Arquivos separados tornariam possível importar arquivos JSON padrão, sem quaisquer metadados. Como as chaves não-folha com valores seriam tratadas neste caso, não está claro.

Como um usuário, eu preferiria ser capaz de importar / exportar para especificações padrão (perdendo metadados) enquanto armazeno os dados reais (incluindo metadados) usando um formato interno elektra arbitrário.

Eu concordo, mas importar / exportar tudo vai um pouco contra a ideia do ponto de montagem da Elektra.

Já sei, ninguém quer implementar isso, mas existe uma solução muito geral:

Se um ponto de montagem usa um plug-in de armazenamento que não oferece suporte a todos os recursos da Elektra, o plug-in de backend cria um arquivo de armazenamento secundário em um formato que oferece suporte a todos os recursos (por exemplo, quickdump , mmapstorage parece um desperdício de espaço em disco aqui). Ao escrever esse ponto de montagem, simplesmente escrevemos com os dois plug-ins. Ao ler, primeiro lemos o arquivo de fallback secundário e, em seguida, o arquivo principal. Isso exigiria um processo de mesclagem, mas usaremos o arquivo principal como fonte de passagem, de modo que a mesclagem seja bastante simples.

Acho que restringir o formato pode ser confuso para os usuários.

Com certeza. Mas é claro para mim que atualmente a Elektra permite muito e algo tem que ser restringido.

Mesmo a solução com vários arquivos requer algum tipo de restrição para configurar nomes de arquivo para evitar colisões.

Originalmente, pensei que a solução mais fácil seria restringir os nomes-chave da Elektra, já que essa é a parte sobre a qual temos mais autoridade. Mas, aparentemente, há aplicativos que usam SSIDs WiFi [1] diretamente como uma parte do nome da chave, então isso não funciona. Pelo menos não sem um grande esforço, como minha proposta mostrou ...
IMO ainda seria a melhor solução para tudo isso apenas para dizer "chave de nome As peças não são seqüências arbitrárias de não-zero bytes mais" e ser feito com ele. Para comparação, POSIX permite apenas os seguintes caracteres em nomes de arquivos:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -

E isso parece ser suficiente para as pessoas. Todos os sistemas de arquivos listados na Wikipedia (exceto aqueles sem diretórios) têm algum tipo de restrição nos nomes dos arquivos.

Quero enfatizar novamente: tudo isso se resume ao fato de que consideramos "Partes do nome da chave são sequências arbitrárias de bytes diferentes de zero" como um axioma [2]. Mudar isso seria muito fácil e resolveria tudo. Pode até ser uma pequena restrição, por exemplo, "Partes do nome da chave são sequências arbitrárias de bytes diferentes de zero, exceto aquelas que começam com @$% e terminam em !%& ao mesmo tempo".
Apenas reservar uma única parte do nome da chave, por exemplo, "As partes do nome da chave são sequências arbitrárias de bytes diferentes de zero, exceto !@& não", nos daria muitas possibilidades. Caramba, mesmo a restrição "a última parte do nome da chave em um nome de chave não deve terminar com @%& " deve ser suficiente. Qualquer tipo de restrição [3], por menor que seja, nos daria margem de manobra para implementar todo tipo de coisa.
Claro, muitas restrições tornam as soluções possíveis, mas uma solução boa e utilizável pode exigir restrições maiores.

Desculpe, se isso parece um discurso retórico, mas em algum ponto fica realmente frustrante que todos concordem que há um problema, mas toda solução é considerada como tendo uma falha ou é vista como muito complicada.


[1] De acordo com a Wikipedia até 802.11-2012, um SSID WiFi tinha "zero a 32 octetos (32 bytes) de comprimento", incluindo zero bytes e "As pilhas de rede sem fio ainda devem estar preparadas para lidar com valores arbitrários no campo SSID", mesmo embora os SSIDs agora devam ser UTF-8 válidos. Portanto, apenas keyAddBaseName ing um SSID WiFi sem qualquer lógica adicional não seria compatível com os padrões de qualquer maneira.

[2] É por isso que a nova documentação em # 3447 começa com partes do nome da chave. É mais fácil (e IMO o mais lógico) explicar os nomes das chaves atuais começando com as partes dos nomes das chaves e continuando a partir daí. Mas a velha maneira de

pegue um caminho do sistema de arquivos Unix / POSIX e adicione um namespace, mas também há uma coisa especial como partes vazias e sequências de escape, e há a versão sem escape - é semi-oculta, mas provavelmente deve ser usada para tudo além da impressão - ah, e as matrizes são uma coisa, também algumas partes são reservadas, mas não realmente reservadas, então não as usamos para nada de baixo nível, ....

mostra muito melhor como os nomes de chave são extremamente complexos e complicados.

[3] Caso você esteja se perguntando, sim # 3447 impõe algumas novas restrições, mas elas são inúteis, porque não afetam o nome da chave sem escape (exceto para o namespace) de nenhuma forma.

Arquivos separados tornariam possível importar arquivos JSON padrão, sem quaisquer metadados. Como as chaves não-folha com valores seriam tratadas neste caso, não está claro.

Discutimos isso em relação à implementação do cache e decidimos não fazer isso. A implementação atual do resolvedor tem garantias de consistência mais fortes do que as que podem ser obtidas ao usar dois arquivos. O resolvedor usa a função atômica rename() para garantir que um processo leia o arquivo antigo ou o novo, mas sempre um arquivo consistente. Infelizmente, isso não pode (que eu saiba) ser feito com vários arquivos com as mesmas garantias. Eu ficaria relutante em usar vários arquivos onde precisamos garantir a consistência.

Eu concordo, mas importar / exportar tudo vai um pouco contra a ideia do ponto de montagem da Elektra.

Verdade.

Tudo isso se resume ao fato de que consideramos "Partes do nome da chave são sequências arbitrárias de bytes diferentes de zero" como um axioma [2].

Eu concordo, esta é a parte onde as restrições fazem mais sentido. Como você disse, os nomes dos arquivos são bastante restritos e ainda funcionam muito bem. A menos que alguém conheça um bom motivo para não restringir nomes de chave (talvez @ markus2330).

Desculpe, se isso parece um discurso retórico

Não, e obrigado por discutir isso. A menos que @ markus2330 saiba alguns motivos pelos quais não podemos mudar isso, estou totalmente aberto à sua sugestão (como restringir !@& ).

Eu ficaria relutante em usar vários arquivos onde precisamos garantir a consistência.

Esse é um bom motivo, contra vários arquivos sim ...

Estou totalmente aberto à sua sugestão (como restringir !@& ).

De forma mais realista, poderíamos impor a restrição: "Um nome de chave não deve conter a parte do nome de chave @elektra " (possivelmente um prefixo mais obscuro, se isso ajudar). Acho que usar elektra pode tornar tudo um pouco mais razoável para os usuários.

Pessoalmente, acho que devemos deixar espaço para o futuro, mas se restringir todos os nomes de chave for muito, também poderíamos restringir o que kdbGet pode retornar e o que kdbSet pode aceitar. Portanto, a restrição acima se aplicaria apenas ao que o último plugin durante kdbGet retorna e ao KeySet dado a kdbSet . Basicamente, apenas restringiríamos quais Chaves podem ser armazenadas do ponto de vista de um aplicativo. Isso seria semelhante ao que já temos com system:/elektra (embora desta vez nós realmente aplicássemos a restrição).

Muito obrigado por essas valiosas discussões. Comecei # 3514 para resumir as decisões importantes espalhadas por toda parte. Por favor, prefira comentar diretamente sobre o texto no # 3514, para que possamos tirar conclusões.

A parte @value é sim. Mas é mais geral. @meta pode ser usado para armazenar metadados dentro de um formato com uma única estrutura de objeto aninhado, como JSON ou TOML (ainda não tenho certeza sobre YAML, porque tags).
Basicamente, como tudo no arquivo JSON se refere a alguma chave em algum lugar, simplesmente não há lugar para armazenar metadados.

Não acho mais que deva ser nosso objetivo contornar as restrições de formatos de arquivo. Se JSON não suporta metadados e valores não-folha, Elektra com um arquivo JSON montado, simplesmente encaminha suas restrições em KeySets. Podemos documentá-los, como proposto em # 3504 e os plug-ins de armazenamento devem falhar em tais KeySets, mas nada mais. (Claro que alguém pode criar um formato de arquivo super-JSON com menos restrições, mas isso está além de nossa mão de obra atual e, como tal, é irrelevante.)

mas os aplicativos que usam @ no início de um campo JSON são provavelmente muito raros.

Quem sabe?

keyAddBaseName (k, "@abc") funciona em ambos os casos, a única diferença é o nome de escape que ele cria.

Soa bem.

mas pelo menos quando você chega aos metadados, ele quebra para certos formatos.

Sim, precisamos abandonar a ideia de que qualquer formato pode suportar qualquer coisa.

Não está claro para mim como o usuário seria capaz de verificar se seus arquivos de configuração estão de acordo com a especificação restrita.

Acho que a maioria dos aplicativos não será muito exigente de qualquer maneira (por exemplo, tem apenas valores-folha e não precisa de nenhum metadado, exceto do tipo), então tudo o que discutimos aqui é relevante apenas para aplicativos excepcionais. Para esses aplicativos, acho melhor que os desenvolvedores de aplicativos desenvolvam seus próprios plug-ins de armazenamento ou usem nossos melhores plug-ins de armazenamento, que oferecem suporte a essas coisas.

@ markus2330 o que você acha sobre a imposição de restrições ao formato?

Não é uma boa ideia. Devemos oferecer suporte aos formatos de arquivo de configuração padronizados. Pode ser um grande problema se alguns arquivos JSON / XML válidos forem rejeitados pela Elektra. Mas, por outro lado, não precisamos apoiar nada mais do que padronizado. Tentar isso foi um erro do passado (tentar agradar a qualquer pessoa).

Precisamos definir nossas prioridades. O que exatamente é uma necessidade absoluta e onde as coisas podem mudar.

doc / GOALS.md em # 3514

A pior parte é que abusa daquela parte que nunca deve ser tocada por um analisador e pode afetar drasticamente a legibilidade de um arquivo de armazenamento.

Concordo que não é a melhor ideia, já teve muitos problemas no plugin ini . badcec5407df6947a67750afd8f0946245c5a5bb

Em vez de dois objetos JSON, também podemos usar arquivos separados.

Ver abaixo.

Para comparação, POSIX permite apenas os seguintes caracteres em nomes de arquivos:

Este é o "conjunto de caracteres de nome de arquivo portátil" e duvido que haja qualquer sistema de arquivo em uso que só suporte isso. Na minha experiência, qualquer interpretação dos nomes dos arquivos só traz problemas (por exemplo, o JFS tinha esses recursos).

E isso parece ser suficiente para as pessoas.

Para a fonte da Elektra, é quase # 1615: wink:

Mas os aplicativos reais imediatamente queriam mais ... (por exemplo, espaços, tremas, ....)

Mudar isso seria muito fácil e resolveria tudo.

Não é tão simples assim: torna os plug-ins de armazenamento muito mais complicados. Ele simplesmente move a lógica para outros lugares.

exceto aqueles que começam com @ $% e terminam em!% & ao mesmo tempo

Essa ideia é semelhante a CDATA . Não é uma solução bonita e difícil de usar na prática.

HERE documentos são um pouco melhores, pois o usuário pode definir a sequência de escape.

Mas para qual recurso exatamente você acha que precisamos? Acho que deveríamos esquecer esses recursos e usar metadados adequadamente para dar semântica às chaves.

Desculpe, se isso parece um discurso retórico, mas em algum ponto fica realmente frustrante que todos concordem que há um problema, mas toda solução é considerada como tendo uma falha ou é vista como muito complicada.

Meu ponto é: talvez não precisemos de uma solução porque o problema não existe.

agora deve ser UTF-8 válido

Eles ainda podem ter caracteres nulos? Por falar nisso. Eu vim com o exemplo SSID porque esse era um requisito real de um cliente real (broadcom). Os caracteres nulos não eram necessários, é óbvio que um char* sem tamanho não pode suportar isso, então nem discutimos sobre isso.

mostra muito melhor como os Key Names são insanamente complexos e complicados.

Sim, mas é melhor que sejam assim do que ter essa lógica em cada aplicativo e plugin de armazenamento.

Caso você esteja se perguntando, sim # 3447 impõe algumas novas restrições

Sim, o nome da chave pode ter quaisquer restrições. Sempre houve a restrição de fuga pendente, então mais algumas restrições não importam. # 3447 será uma grande melhoria para a Elektra.

Infelizmente, isso não pode (que eu saiba) ser feito com vários arquivos com as mesmas garantias

Isso pode ser feito escrevendo um registro de diário onde você escreve tudo o que planeja fazer e, em caso de qualquer problema, você pode recuperar reproduzindo o diário. Implementar isso está muito além do nosso poder humano. Também não se ajusta realmente a um sistema de configuração (nem sistemas de arquivos), é uma técnica para bancos de dados estruturados.

Eu tornei isso um não objetivo em multiple_file_backends.md 59066aa99bae707d0f0178841513fd3b8590b5bc

Basicamente, apenas restringiríamos quais Chaves podem ser armazenadas do ponto de vista de um aplicativo. Isso seria semelhante ao que já temos com system: / elektra (embora desta vez nós realmente aplicássemos a restrição).

Podemos aplicar a restrição de system:/elektra . Mas por que você deseja restringir quais aplicativos estão armazenando em sua parte da hierarquia?

Acho que é melhor que os desenvolvedores de aplicativos desenvolvam seus próprios plug-ins de armazenamento

Derrotando assim um dos principais benefícios do Elektra: "O administrador / usuário decide o formato de configuração, não o desenvolvedor do aplicativo".

Pode ser um grande problema se alguns arquivos JSON / XML válidos forem rejeitados pela Elektra

Essa nunca foi minha sugestão. Claro que devemos aceitar todos os JSON válidos. A questão é o que KeySet produzimos. Se usarmos "@value" para valores que não sejam folha, conforme sugerido acima, ainda poderemos aceitar todos os JSON válidos. O KeySet resultante teria apenas uma estrutura ligeiramente diferente algumas vezes.

Para comparação, POSIX permite apenas os seguintes caracteres em nomes de arquivos:

Este é o "conjunto de caracteres de nome de arquivo portátil" e duvido que haja qualquer sistema de arquivo em uso que só suporte isso. Na minha experiência, qualquer interpretação dos nomes dos arquivos só traz problemas (por exemplo, o JFS tinha esses recursos).

E isso parece ser suficiente para as pessoas.

Para a fonte da Elektra é quase # 1615

Mas os aplicativos reais imediatamente queriam mais ... (por exemplo, espaços, tremas, ....)

Eles ainda não permitem / ou nomes vazios. A maioria também tem comprimentos máximos para nomes de arquivos e caminhos. A questão é que os aplicativos encontram maneiras de contornar as limitações. E, no nosso caso, podemos até ajudá-los com bibliotecas.

Não é tão simples assim: torna os plug-ins de armazenamento muito mais complicados. Ele simplesmente move a lógica para outros lugares.

Eu não concordo. Os plug-ins de armazenamento já são extremamente complexos, relativamente falando, isso seria apenas um pequeno inconveniente. (assumindo que fornecemos uma boa biblioteca storage com funções auxiliares)

Essa ideia é semelhante ao CDATA. Não é uma solução bonita e difícil de usar na prática.

Os documentos AQUI são um pouco melhores, pois o usuário pode definir a sequência de escape.

Ambos os documentos CDATA e HERE precisam reservar alguma sintaxe, do ponto de vista atual da Elektra, não há diferença. Ambas as versões são uma restrição aos nomes das chaves.

Além disso, ambos são _muito_ mais poderosos do que o que propus. Minha proposta só "escaparia" de uma parte completa do nome da chave de cada vez.

Acho que deveríamos esquecer esses recursos e usar metadados adequadamente para dar semântica às chaves.

Você acabou de dizer que alguns plug-ins de armazenamento podem não suportar metadados. Portanto, parece que esta não é uma opção.

Meu ponto é: talvez não precisemos de uma solução porque o problema não existe.

Claro, se você mudar de ideia e dizer que um formato de armazenamento pode limitar as habilidades da Elektra, o problema desaparece. Mas isso muda fundamentalmente a promessa da Elektra aos usuários. Limitaríamos todos os usuários apenas para permitir que algum desenvolvedor protegesse algumas linhas de código que lidam com a codificação de valores especiais.

Eles ainda podem ter caracteres nulos?

Provavelmente, NUL é um caractere UTF-8 válido.

sem tamanho não pode suportar isso

Bem, o tamanho máximo de um SSID é de 32 bytes, então você não precisa passar o tamanho ao redor, desde que o buffer seja sempre de 32 bytes e preenchido com zeros.

Sim, o nome da chave pode ter quaisquer restrições.

Por favor, decida-se. Durante todo esse tempo, você argumentou que não pode haver nenhuma restrição.

Sempre houve a restrição de fuga pendente, então mais algumas restrições não importam.

"Fuga pendente" não é uma restrição. É um erro de sintaxe no nome da chave com escape. Os nomes de chave escapados nunca foram strings arbitrárias. Isso é uma coisa totalmente diferente.

Podemos aplicar a restrição de system:/elektra .

Poderíamos exigir um sinalizador em keyNew para permitir tais nomes. Caso contrário, um aplicativo que aceita nomes de chave do usuário, teria que limpar a entrada. Veja também o problema kdb import em # 3299.

Mas por que você deseja restringir quais aplicativos estão armazenando em sua parte da hierarquia?

Não quero restringir _quais_ aplicativos são armazenados, mas _como_ eles estão armazenando. Isso dá aos plug-ins (armazenamento) mais liberdade.

Derrotando assim um dos principais benefícios do Elektra: "O administrador / usuário decide o formato de configuração, não o desenvolvedor do aplicativo".

Nunca foi possível que qualquer plugin de armazenamento pode ser usado para qualquer aplicação. Isso não significa que retiramos o poder do administrador / usuário de alterar os pontos de montagem. Mas precisamos ser honestos e deixar de lado a responsabilidade de que isso envolve alguns riscos.

Essa nunca foi minha sugestão. Claro que devemos aceitar todos os JSON válidos. A questão é que KeySet produzimos. Se usarmos "@value" para valores não folha como sugerido acima, ainda poderíamos aceitar todos os JSON válidos. O KeySet resultante teria apenas uma estrutura ligeiramente diferente algumas vezes.

Neste problema já perdemos muitas horas em cerca de 10 anos, sem qualquer progresso. A primeira ideia era keytometa, depois directoryvalue, com várias etapas intermediárias. Por que não aceitar JSON como ele é? Funcionará para a maioria dos aplicativos. Uma estrutura ligeiramente melhor realmente vale a pena?

A questão é que os aplicativos encontram maneiras de contornar as limitações.

Os aplicativos até encontram maneiras de contornar a ausência de uma biblioteca de configuração. Por que eles usariam uma biblioteca de configuração que lhes dá limitações que atualmente não têm? É bastante trivial implementar um arquivo de propriedades que permite qualquer nome de chave com qualquer valor. Por que o Elektra seria útil se nem mesmo oferece isso?

E, no nosso caso, podemos até ajudá-los com bibliotecas.

Primeiro, precisamos esclarecer os objetivos antes de fazermos soluções complexas.

Eu não concordo. Plug-ins de armazenamento já são extremamente complexos,

Você olhou para simpleini, ni, c ou mini? Você ainda pode escrever facilmente um plugin de armazenamento útil em menos de um dia.

relativamente falando, isso seria apenas um pequeno inconveniente. (assumindo que fornecemos uma boa biblioteca de armazenamento com funções auxiliares)

Infelizmente, a suposição não é válida. Também tentamos criar bibliotecas auxiliares há muitos anos, com muito pouco sucesso. O que é feito no core de maneira adequada sempre foi a melhor solução.

Os documentos CDATA e HERE precisam reservar alguma sintaxe; do ponto de vista atual da Elektra, não há diferença. Ambas as versões são uma restrição aos nomes das chaves.

Não, os documentos HERE não reservam sintaxe. Você pode decidir rapidamente (por exemplo, com base nos dados) qual palavra-chave deseja usar para marcar o final do documento.

Acho que deveríamos esquecer esses recursos e usar metadados adequadamente para dar semântica às chaves.
Você acabou de dizer que alguns plug-ins de armazenamento podem não suportar metadados. Portanto, parece que esta não é uma opção.

A maneira correta é especificar chaves no namespace spec . Os plug-ins de armazenamento nos outros namespaces não precisam armazenar nenhum metadado. Consulte a decisão arbitrary_metadata.md em # 3514

Claro, se você mudar de ideia e dizer que um formato de armazenamento pode limitar as habilidades da Elektra, o problema desaparece. Mas isso muda fundamentalmente a promessa da Elektra aos usuários. Limitaríamos todos os usuários apenas para permitir que algum desenvolvedor protegesse algumas linhas de código que lidam com a codificação de valores especiais.

Separei esta questão para # 3515

Sim, o nome da chave pode ter quaisquer restrições.
Por favor, decida-se. Durante todo esse tempo, você argumentou que não pode haver nenhuma restrição.

Nomes de chaves também conhecidos keySetName podem ter restrições (ou seja, falha para alguns argumentos), nomes de partes de chaves também conhecidos keySetBaseName não podem ter restrições (nunca falha em nenhum argumento). Não sou fanático nem dogmático, podemos discutir isso e tudo mais se você vir um problema fundamental com nossos objetivos mais importantes.

Podemos impor a restrição do sistema: / elektra.
Poderíamos exigir um sinalizador em keyNew para permitir esses nomes. Caso contrário, um aplicativo que aceita nomes de chave do usuário, teria que limpar a entrada.

Eu estava pensando em um plugin que rejeita qualquer coisa escrita em /elektra que não confirma quais ferramentas têm permissão para escrever lá. Eu acho que é de baixa prioridade, no entanto.

Não, os documentos HERE não reservam sintaxe. Você pode decidir rapidamente (por exemplo, com base nos dados) qual palavra-chave deseja usar para marcar o final do documento.

Sim, eles fazem << ainda está reservado para iniciar documentos AQUI. O marcador final é definido pelo usuário, mas o início obviamente não pode ser.
De qualquer forma, isso não é importante.


Nunca foi possível usar qualquer plugin de armazenamento para qualquer aplicativo.

Está tudo bem para mim, se nem todos os plug-ins suportam tudo, mas se um aplicativo usa um plug-in de armazenamento personalizado, o administrador / usuário não tem escolha. Deve haver pelo menos alguma escolha, mesmo que seja apenas YAML ou TOML. Se apenas um formato personalizado feito sob medida para Elektra suporta tudo, então temo que ninguém usará Elektra. Para mim, um dos recursos mais importantes do Elektra é que um amdin / usuário sempre pode usar seu formato de configuração favorito, não importa o aplicativo.

Você olhou para simpleini, ni, c ou mini? Você ainda pode escrever facilmente um plugin de armazenamento útil em menos de um dia.

c é somente gravação. mini não oferece suporte a metadados e AFAICT exclui todos os comentários de um arquivo. simpleini também não suporta metadados e relaciona muito mais restrições no README.

Em geral, os plug-ins INI não são um bom exemplo, porque o INI não tem realmente uma especificação, portanto, não há limitações provenientes do formato.

ni é baseado em uma biblioteca existente. É por isso que o código é bastante curto e simples.

Mas ni é realmente um bom exemplo do que eu gostaria de fazer. Ele usa uma interpretação muito específica de arquivos INI que pode não ser desejada pelos desenvolvedores de aplicativos. Na verdade, isso levanta outra questão.

Qual é o caso de uso mais importante?

  1. Converter um aplicativo existente para Elektra e manter os arquivos de configuração iguais
  2. Escrever novos aplicativos cujo formato de configuração será baseado no que se encaixa melhor para Elektra

Para o primeiro caso, precisamos de plug-ins que possam ler qualquer arquivo e produzir KeySet s úteis.
Para o segundo caso, mesmo restrições severas como aquelas impostas por ni podem não ser um problema.

A maneira correta é especificar chaves no namespace spec . Os plug-ins de armazenamento nos outros namespaces não precisam armazenar nenhum metadado.

Sim, esta é uma solução possível. Mas requer muito trabalho para que spec funcione corretamente. No mínimo, precisamos de algumas garantias de ordenação do plugin dentro da posição postgetstorage .

Mas causa algumas dificuldades com metadados inferidos do formato de armazenamento (por exemplo, tipo, array). Seria um erro se lêssemos uma matriz JSON sem array metadados correspondentes em spec ?

No entanto, isso não resolve o problema de chaves não-folha com valores.

Nomes de chaves também conhecidos keySetName podem ter restrições (ou seja, falha para alguns argumentos), nomes de partes de chaves também conhecidos keySetBaseName não podem ter restrições (nunca falha em nenhum argumento).

Essas são duas coisas totalmente diferentes. keySetName aceita um nome de chave com escape , enquanto keySetBaseName aceita uma parte de um nome de chave sem escape . É claro que um nome de chave com escape tem restrições.

No entanto, tudo em torno dos nomes de chave da Elektra é baseado em uma _parte de nome de chave_ (consulte também o documento em # 3447). Portanto, a única questão que precisamos discutir é:

_O que é uma parte do nome da chave? _

Está tudo bem para mim, se nem todos os plug-ins suportam tudo, mas se um aplicativo usa um plug-in de armazenamento personalizado, o administrador / usuário não tem escolha.

Não vejo como isso seria possível. Na Elektra, você sempre pode implementar alternativas, desde que essa alternativa produza KeySets adequados para a aplicação. A única coisa consertada é o KeySet, mas como o KeySet é produzido é sempre algo intercambiável. Para mim, este é o principal benefício da Elektra.

É por isso que o KeySet (incluindo os nomes das chaves) são as decisões mais importantes (e mais difíceis) de todas.

Deve haver pelo menos alguma escolha, mesmo que seja apenas YAML ou TOML. Se apenas um formato personalizado feito sob medida para Elektra suporta tudo, então temo que ninguém usará Elektra. Para mim, um dos recursos mais importantes do Elektra é que um amdin / usuário sempre pode usar seu formato de configuração favorito, não importa o aplicativo.

Não vejo como nenhuma das decisões de que estamos falando afeta a possibilidade. Se você colocar esforço suficiente em um plug-in de armazenamento para seu formato de configuração favorito (incluindo extensões sintáticas ou semelhantes), você poderá colocar qualquer aplicativo em execução.

mini não oferece suporte a metadados e AFAICT exclui todos os comentários de um arquivo. O simpleini também não suporta metadados e lista muito mais restrições no README.

Para a maioria dos aplicativos, essas restrições são irrelevantes. Uma ferramenta que uso funciona com o simpleini e também com o mini como back-ends.

Acho que já chegamos quase à mesma conclusão: o que quer que aconteça para produzir o KeySet correto, precisa acontecer dentro do plugin de armazenamento. Usar uma "biblioteca de armazenamento" é obviamente vantajoso, mas no final é um detalhe de implementação. A ideia de que "plug-ins posteriores corrigem o que o plug-in de armazenamento fez de errado" falhou. Então, por que precisamos de mais sintaxe no nome da chave? Qualquer sintaxe necessária pode ser eliminada no plug-in de armazenamento.

  1. Converter um aplicativo existente para Elektra e manter os arquivos de configuração iguais
  2. Escrever novos aplicativos cujo formato de configuração será baseado no que se encaixa melhor para Elektra

Imho "1" é mais importante agora, pois precisamos disso para o KDE. Então, de alguma forma, precisamos do Elektra em uma forma que não destrua o plugin kconfig .

Sobre "2" Não sei o que significa "se encaixa melhor para Elektra". A Elektra não tem um propósito para si mesma, sua única finalidade é atender às necessidades de desenvolvedores, usuários e administradores.

Mas causa algumas dificuldades com metadados inferidos do formato de armazenamento (por exemplo, tipo, array). Seria um erro ler um array JSON que não tem metadados de array correspondentes nas especificações?

Não, apenas a outra forma é um erro: se a especificação requer um array, mas não há nenhum.

Sim, esta é uma solução possível. Mas é preciso muito trabalho para que as especificações funcionem corretamente. No mínimo, precisamos de algumas garantias de ordenação do plugin na posição postgetstorage.

Sim, concordo totalmente. E algo precisa ser feito com spec qualquer maneira, não podemos deixar como está.

No entanto, isso não resolve o problema de chaves não-folha com valores.

Você argumentou que isso não é importante de qualquer maneira: stick_out_tongue_winking_eye:

E eu concordo, para quase todos os aplicativos não será importante.

O que é uma parte do nome da chave?

Você pode fazer uma questão que lista os pontos em aberto / pouco claros? Ou melhor ainda: adicioná-lo a # 3514?

Está tudo bem para mim, se nem todos os plug-ins suportam tudo, mas se um aplicativo usa um plug-in de armazenamento personalizado, o administrador / usuário não tem escolha.

Não vejo como isso seria possível. Na Elektra, você sempre pode implementar alternativas, desde que essa alternativa produza KeySets adequados para a aplicação. A única coisa consertada é o KeySet, mas como o KeySet é produzido é sempre algo intercambiável. Para mim, este é o principal benefício da Elektra.

É por isso que o KeySet (incluindo os nomes das chaves) são as decisões mais importantes (e mais difíceis) de todas.

Deve haver pelo menos alguma escolha, mesmo que seja apenas YAML ou TOML. Se apenas um formato personalizado feito sob medida para Elektra suporta tudo, então temo que ninguém usará Elektra. Para mim, um dos recursos mais importantes do Elektra é que um amdin / usuário sempre pode usar seu formato de configuração favorito, não importa o aplicativo.

Não vejo como nenhuma das decisões de que estamos falando afeta a possibilidade. Se você colocar esforço suficiente em um plug-in de armazenamento para seu formato de configuração favorito (incluindo extensões sintáticas ou semelhantes), você poderá colocar qualquer aplicativo em execução.

>

Eu deveria ter adicionado mais contexto à minha resposta. Acho que estamos na página a esse respeito. Meu comentário foi em resposta a esta declaração sua:

Acho que a maioria dos aplicativos não será muito exigente de qualquer maneira (por exemplo, tem apenas valores-folha e não precisa de nenhum metadado, exceto do tipo), então tudo o que discutimos aqui é relevante apenas para aplicativos excepcionais. Para esses aplicativos, acho melhor que os desenvolvedores de aplicativos desenvolvam seus próprios plug-ins de armazenamento ou usem nossos melhores plug-ins de armazenamento, que oferecem suporte a essas coisas.

Em particular a parte: "Acho que é melhor que os desenvolvedores de aplicativos desenvolvam seus próprios plug-ins de armazenamento"

Embora sempre seja uma opção, acho que _nunca_ deve ser algo que recomendamos ou mesmo sugerimos como solução. Usar um plugin de armazenamento customizado não estaria de acordo com a filosofia da Elektra e deve ser evitado tanto quanto possível. Nota: por "plug-in de armazenamento personalizado", quero dizer um plug-in projetado para funcionar com um aplicativo específico, mas não oferece garantias de compatibilidade com o resto do Elektra. Estaria tudo bem se alguém quiser usar um formato personalizado e desenvolver um plugin correspondente que seja compatível com o ambiente Elektra padrão.

Acho que já chegamos quase à mesma conclusão: o que quer que aconteça para produzir o KeySet correto, precisa acontecer dentro do plugin de armazenamento. Usar uma "biblioteca de armazenamento" é obviamente vantajoso, mas no final é um detalhe de implementação. A ideia de que "plug-ins posteriores corrigem o que o plug-in de armazenamento fez de errado" falhou.

Sim, é basicamente isso. O plug-in de armazenamento não pode depender de outros plug-ins (exceto talvez valores binários e coisas assim).

Embora talvez um plugin seja a solução, afinal. Vou ter que pensar mais sobre isso e postar a ideia, se achar que funciona.

Mas causa algumas dificuldades com metadados inferidos do formato de armazenamento (por exemplo, tipo, array). Seria um erro ler um array JSON que não tem metadados de array correspondentes nas especificações?

Não, apenas a outra forma é um erro: se a especificação requer um array, mas não há nenhum.

Vamos dar um passo adiante. E se tivermos este JSON [ "a", "b" ] sem especificações e exportá-lo para um formato sem metadados e sem matrizes (por exemplo, mini )? As informações de que se trata de uma matriz seriam perdidas.

Como este é um caso extremo, podemos apenas dizer: Isso é lamentável, mas é o que é.

E eu concordo, para quase todos os aplicativos não será importante.

O mesmo pode ser dito sobre o uso de nomes de chave arbitrários. Quase todos os aplicativos não teriam problemas se não pudessem usar /@elektra/ em seus nomes de chave.

Você pode fazer uma questão que lista os pontos em aberto / pouco claros? Ou melhor ainda: adicioná-lo a # 3514?

Farei uma lista em algum lugar, para que possamos discutir na segunda-feira.

Estaria tudo bem se alguém quiser usar um formato personalizado e desenvolver um plugin correspondente que seja compatível com o ambiente Elektra padrão.

Na verdade, eu estava pensando assim. Mas sim, particularidades facilmente se insinuam. Por exemplo, o plug-in kconfig os metadados podem ter apenas um único caractere, então obviamente não serão muito compatíveis com nossos metadados (pelo menos desde que o analisador não remapeie este caractere ao significado real, o que no momento não acontece). No momento, simplesmente passamos os metadados de um caractere pela nossa camada e, se necessário, fazemos na biblioteca kconfig o que teria acontecido se ela tivesse analisado diretamente o arquivo.

@mpranj você já verificou se isso realmente funciona? Pelo menos [$e] parece existir com bastante frequência.

Embora talvez um plugin seja a solução, afinal. Vou ter que pensar mais sobre isso e postar a ideia, se achar que funciona.

No momento, prefiro que consertemos as coisas que já sabemos como consertar.

Como este é um caso extremo, podemos apenas dizer: Isso é lamentável, mas é o que é.

Exatamente, se você deseja o "recurso X", não pode ter um plugin sem este recurso na cadeia de importação / exportação. O mesmo com comentários e assim por diante.

chaves não-folha com valores.
O mesmo pode ser dito sobre o uso de nomes de chave arbitrários. Quase todos os aplicativos não teriam problemas se não pudessem usar / @ elektra / em seus nomes de chave.

sim. Mas também há uma grande diferença entre algo que não funciona com alguns plug-ins e algo que nunca funcionará com Elektra.

Farei uma lista em algum lugar, para que possamos discutir na segunda-feira.

: +1:

Mas também há uma grande diferença entre algo que não funciona com alguns plug-ins e algo que nunca funcionará com Elektra.

Entendi, mas, de forma realista, com que frequência não ter /@elektra/ chaves será realmente um problema?

Embora talvez um plugin seja a solução, afinal. Vou ter que pensar mais sobre isso e postar a ideia, se achar que funciona.

No momento, prefiro que consertemos as coisas que já sabemos como consertar.

A ideia era um plugin que está sempre montado e faz alguma codificação / decodificação de nomes de chaves. Então, um plugin de armazenamento só precisa lidar com KeySet s que, por exemplo, não contêm /@elektra/ chaves. Mas, por causa da codificação, o aplicativo ainda pode usar qualquer nome de chave. O plugin de armazenamento pode então usar chaves /@elektra/ para seu próprio propósito, por exemplo, metadados e valores não-folha.

O efeito seria uma pequena limitação nos arquivos de armazenamento, mas nenhuma limitação para os aplicativos. A complexidade dos plug-ins de armazenamento também não seria afetada, porque o plug-in de armazenamento não precisa usar nenhuma chave /@elektra/ . Apenas os plug-ins que desejam oferecer suporte, por exemplo, aos metadados, precisam escrever código adicional, mas é sempre esse o caso.

Entendi, mas, de forma realista, com que frequência não ter as chaves / @ elektra / realmente será um problema?

Provavelmente sem problema algum. Mas será um problema agora, tanto quanto será mais tarde. Então, por que reservar agora e não quando realmente encontrarmos um caso de uso em que algo assim seja necessário? Então sabemos que não é apenas uma fantasia e podemos escolher um nome apropriado.

Em linguagens de programação, (normalmente) reservamos palavras-chave apenas quando fazemos extensões sintáticas.

por exemplo, metadados

Para metadados em chaves, spec é a melhor solução, pois se refere a todos os namespaces. Metadados não específicos são basicamente apenas preservação de formatação útil e similares.

porque o plugin de armazenamento não precisa usar nenhuma chave / @ elektra /

Não é que um plugin de armazenamento use qualquer nome, a questão é o comportamento se encontrar <strong i="14">@elektra</strong> = something em um arquivo.

Então, por que reservar agora e não quando realmente encontrarmos um caso de uso em que algo assim seja necessário?

Porque esta é uma mudança enorme e antes do 1.0 é o momento certo para fazer essas coisas. Especialmente porque já estão mudando os nomes das chaves.

Também há um caso de uso muito real para ele agora. No mínimo, ele permite armazenar chaves não-folha com valores em qualquer formato.

Para metadados em chaves, spec é a melhor solução, pois se refere a todos os namespaces.

Vou apenas mencionar array . Pense um pouco sobre as coisas em # 3514 e, em seguida, diga-me como armazenar adequadamente um array em um arquivo de propriedades Java.

Seria bom se os metadados fossem armazenados apenas em spec:/ (isso também resolveria alguns problemas com o plug-in spec ), mas exigiria algumas mudanças muito grandes no Elektra para que funcionasse bem.

a questão é o comportamento se encontrar <strong i="17">@elektra</strong> = something em um arquivo

Se o plugin usa @elektra para codificar algo (por exemplo, valores não-folha) então é o que acontece.
Caso contrário: "ERROR: nome de chave ilegal"

Farei uma lista em algum lugar, para que possamos discutir na segunda-feira.

Conforme prometido em https://github.com/ElektraInitiative/libelektra/issues/3223#issuecomment -709389141, agora adicionei # 3517.

diga-me como armazenar adequadamente uma matriz em um arquivo de propriedades Java.

Só funciona com spec .

mas exigiria algumas mudanças muito grandes no Elektra para que funcionasse bem.

Existem algumas alterações necessárias que ainda não estão no rastreador de problemas? Eu acho que é obrigatório para o 1.0 que pelo menos o básico da especificação funcione bem (e para se livrar das coisas que não funcionam).

Só funciona com spec .

Mas como? Você precisa dos metadados array nos outros namespaces para saber o tamanho real do array.

Existem algumas alterações necessárias que ainda não estão no rastreador de problemas? Eu acho que é obrigatório para o 1.0 que pelo menos o básico da especificação funcione bem (e para se livrar das coisas que não funcionam).

É impossível dizer. Precisamos decidir o que a especificação realmente deve fazer. Então, precisamos descobrir se e como isso é possível. Mesmo assim, é muito provável que encontremos alguns casos extremos que não funcionam. Elektra é tão complicado que é quase impossível pensar nisso e uma boa cobertura de teste é pelo menos tão difícil. Muito da Elektra ainda é baseado em princípios vagamente ou não definidos.

O maior problema são definitivamente as posições atuais do plugin. Mas isso vai dar muito trabalho para consertar. IMO, essa parte precisa essencialmente de um redesenho completo.

Mas como? Você precisa dos metadados do array nos outros namespaces para saber o quão grande o array realmente é.

Sim, a especificação realmente precisa entender a semântica dos metadados, como arrays. Portanto, ele verificaria como o array realmente se parece e, em seguida, adicionaria os metadados apropriados array .

Elektra é tão complicado que é quase impossível pensar nisso e uma boa cobertura de teste é pelo menos tão difícil.

Eu concordo, então deixe ser mais simples. Agora é a oportunidade perfeita. Aprendemos muito sobre o que não pode ser feito. Então, vamos nos livrar dessas coisas.

O maior problema são definitivamente as posições atuais do plugin. Mas isso vai dar muito trabalho para consertar. IMO, essa parte precisa essencialmente de um redesenho completo.

Estou cada vez mais concordando com @mpranj que ganchos para plug-ins globais específicos não é uma ideia tão ruim. Os requisitos para esses plug-ins são bastante complicados e, portanto, o posicionamento genérico se tornaria muito complicado.

Portanto, simplesmente não teríamos posições de plug-ins globais genéricas, mas apenas as específicas para mmap, spec e notification (o único que realmente precisamos para 1.0). Posições genéricas seriam boas, mas está claramente além de nossa capacidade de testar isso. Modifiquei a decisão em 89b29034e1d505f36d298f01bf0fcfd13aa1af70

Mais discussões, por favor em # 3514

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

mpranj picture mpranj  ·  3Comentários

mpranj picture mpranj  ·  3Comentários

sanssecours picture sanssecours  ·  4Comentários

markus2330 picture markus2330  ·  3Comentários

sanssecours picture sanssecours  ·  3Comentários