Como operador

    O como operador em Pony tem dois usos relacionados. Em primeiro lugar, fornece uma maneira segura de aumentar a especificidade do tipo de objeto (fundição). Segundo, dá ao programador uma maneira de especificar literalmente o tipo dos itens de uma matriz.

Conversão segura para um tipo mais específico (fundição)

    O como operador pode ser usado para criar uma referência a um objeto com um tipo mais específico do que a referência dada, se possível. Isto pode ser aplicado a tipos que estão relacionados por herança, assim como a uniões e cruzamentos. Isto é feito em tempo de execução, e se falhar, então um erro é levantado.
      Vejamos um exemplo. O pacote json fornece um tipo chamado JsonDoc que pode tentar analisar as cordas como fragmentos do JSON. O valor analisado é armazenado no campo de dados do objeto, e o tipo desse campo é a união (F64 | I64 | Bool | Nenhuma | String | JsonArray | JsonObject). Portanto, se houver um objeto JsonDoc referenciado por jsonDoc, então jsonDoc.parse("42") armazenará um I64 igual a 42 nos dados jsonDoc.data. Se o programador quiser tratar o jsonDoc.data como um I64 então ele pode obter uma referência I64 aos dados usando o jsonDoc.data como I64.
        No programa seguinte, os argumentos da linha de comando são analisados como Json. É mantida uma soma corrente de todos os argumentos que podem ser analisados como números I64, e todos os outros argumentos são ignorados.

      use "json"
      
      actor Main
        new create(env: Env) =>
          var jsonSum: I64 = 0
          let jd: JsonDoc = JsonDoc
          for arg in env.args.slice(1).values() do
            try
              jd.parse(arg)?
              jsonSum = jsonSum + (jd.data as I64)
            end
          end
          env.out.print(jsonSum.string())

        Quando executado com os argumentos 2 e 4 e 7 e 15, a saída do programa é 28.
          A mesma coisa pode ser feita com interfaces, usando como referência uma interface ou classe mais específica. Digamos, por exemplo, que você tenha uma biblioteca para fazer coisas com criaturas peludas, parecidas com o rodent-like. Ela fornece uma interface Critter que os programadores podem então usar para criar tipos específicos de criaturas.

        interface Critter
          fun wash(): String

          O programador usa esta biblioteca para criar uma Wombat e uma classe Capybara. Mas a classe Capybara fornece um novo método, nadar(), que não faz parte da classe Critter. O programador quer armazenar todas as criaturas em uma matriz, a fim de realizar ações em grupos de criaturas. Agora, suponha que quando as capivaras terminarem de lavar, elas queiram ir nadar. O programador pode fazer isso usando como tentativa de usar cada objeto Critter no Array[Critter] como uma Capivara. Se isto falhar porque o Critério não é uma Capivara, então um erro é levantado; o programa pode engolir este erro e passar para o próximo item.

        interface Critter
          fun wash(): String
        
        class Wombat is Critter
          fun wash(): String => "I'm a clean wombat!"
        
        class Capybara is Critter
          fun wash(): String => "I feel squeaky clean!"
          fun swim(): String => "I'm swimming like a fish!"
        
        actor Main
          new create(env: Env) =>
            let critters = Array[Critter].>push(Wombat).>push(Capybara)
            for critter in critters.values() do
              env.out.print(critter.wash())
              try
                env.out.print((critter as Capybara).swim())
              end
            end

          Especifique o tipo de itens em uma matriz literal

            O como operador pode ser usado para dizer ao compilador que tipo usar para os itens de uma matriz literal. Em muitos casos, o compilador pode inferir o tipo, mas às vezes ele é ambíguo.
              Por exemplo, no caso do programa seguinte, o método foo pode tomar como argumento ou um Array[U32] ref ou um Array[U64] ref. Se um Array[U64] é passado como argumento para o método e nenhum tipo é especificado, então o compilador não pode deduzir o correto porque existem dois igualmente válidos.

            actor Main
              fun foo(xs: (Array[U32] ref | Array[U64] ref)): Bool =>
                // do something boring here
                true
            
              new create(env: Env) =>
                foo([as U32: 1; 2; 3])
                // the compiler would complain about this:
                //   foo([1; 2; 3])

              O tipo solicitado deve ser um tipo válido para os itens da matriz. Como estes tipos são verificados no momento da compilação, é garantido que funcionem, portanto não há necessidade de o programador lidar com uma condição de erro.

            Sistema de pacotes (encapsulamento)

              O código Pony está organizado em pacotes. Cada programa e biblioteca é um único pacote, possivelmente usando outros pacotes.

            A estrutura dos pacotes

              O pacote é a unidade básica de código no Pony. Ele corresponde diretamente a um diretório no sistema de arquivos, todos os arquivos fonte do Pony dentro desse diretório estão dentro desse pacote. Note que isto não inclui arquivos em nenhum subdiretório. Cada arquivo fonte está dentro de exatamente um pacote. Portanto, todo o código Pony está em pacotes. Um pacote é normalmente dividido em vários arquivos fonte, embora não tenha que estar. Isto é puramente uma conveniência para permitir uma melhor organização do código e o compilador trata todo o código dentro de um pacote como se ele fosse de um único arquivo. O pacote é o limite de privacidade para tipos e métodos. Ou seja, o pacote é o limite de privacidade para tipos e métodos:

          • Tipos privados (aqueles cujo nome começa com um sublinhado) podem ser usados somente dentro do pacote no qual estão definidos.
          • Os métodos privados (aqueles cujo nome começa com um sublinhado) podem ser chamados somente a partir do código dentro do pacote no qual eles estão definidos.
            • Segue-se que todo código dentro de um pacote é suposto conhecer e confiar, todo o resto do código no pacote. Não existe tal conceito como um sub-pacote no Pony. Por exemplo, os pacotes "foo/bar" e "foo/bar/wombat" irão, presumivelmente, realizar tarefas relacionadas, mas são dois pacotes independentes. O pacote "foo/bar" não contém o pacote "foo/bar/wombat" e tampouco tem acesso aos elementos privados do outro.