Escreva um trecho de código para gerar o número da linha da declaração de impressão / saída (no formato “Hello World, da linha X!”)


25

O desafio

Escreva um programa que produz Hello World, from line X!, onde Xestá o número da linha, no código-fonte, da própria declaração de impressão.

As regras

  • Nesse contexto, queremos que o primeiro número da linha da instrução que gera a string seja exibido parastdout
  • Você deve evitar simplesmente pesquisar seu código-fonte como uma string (arquivo ou quine) para encontrar o número da linha
  • Se qualquer espaço em branco ou instrução adicional (que não interrompa o fluxo do código) for adicionado ao código-fonte, ele deverá ser refletido no tempo de execução (após a compilação, se aplicável)

Recomendações

Se fornecido pelo idioma, você poderá usar exceções / rastreamentos de pilha para atingir esse objetivo. Tente o seu melhor para usar um código portátil em diferentes sistemas / implementações, mas observe que isso não é um requisito. O uso de variáveis ​​definidas como __LINE__, embora permitido pelas regras, é desencorajado.

O vencedor

  • Este é um concurso de popularidade (encerrado em 10 de junho de 2014), em que a resposta mais votada pela comunidade será declarada vencedora com base nos votos atuais no momento

  • Ao votar, considere a criatividade da resposta de alguém, quão elaborada ou interessante é. e as dificuldades / restrições da linguagem de programação que está sendo usada


O que você quer dizer com "o número da primeira linha"? Você está falando sobre o que deve acontecer se a declaração se estender por várias linhas?
User2357112 suporta Monica

@ user2357112 sim, apenas para resolver qualquer ambiguidade, se alguém precisar usar uma instrução milti-line.
Revelação

O título é muito explícito, mas talvez um pouco longo.
primo

1
As respostas para isso são todas chatas porque é uma pergunta tão ruim. É como se o solicitante não soubesse da existência do LINE . Na verdade, eu me inscrevi especificamente para votar abaixo, eu pensei que era tão ruim.
dave

1
@ Markasoftware se uma linha foi adicionada antes dela, a saída não mudaria para refletir isso.
primo

Respostas:


48

Sinclair Basic

10 PRINT "Hello world, from line ";PEEK 23621;"!"

Olá mundo, da linha 10!

Isso funcionará para qualquer linha PEEKinserindo o endereço que armazena o número da linha atual; portanto, o seguinte também funcionará:

341 PRINT "Hello world, from line ";PEEK 23621;"!"

Olá mundo, da linha 341!


E da mesma forma, Timex / Sinclair BASIC!
Gabe

Não pretendo conhecer esse idioma, mas você não pode deixar de fora o STR$que substitui os +sinais por ponto e vírgula?
Lister

@ MrLister Sim, isso definitivamente funcionaria, mas eu sempre uso +s por hábito.
precisa saber é o seguinte

40

BASIC

Eu acho que isso faz tudo o que foi solicitado:

10 PRINT "Hello World, from line 10!"

5
If any additional whitespace or statements (which do not interrupt the flow of the code) is added to the source code, it should be reflected at run-time (after compiling if applicable). A intenção está lá. Além disso, essa é a primeira linha da fonte, não a 10ª.
precisa saber é o seguinte

30
Pode ser a primeira linha do código-fonte, mas ainda é a linha 10 .
Ossifrage melindroso

13
Eu acredito que isso se enquadra firmemente na categoria não mais engraçada . É realmente sem imaginação e desinteressante, embora literalmente atenda ao requisito. Por que isso tem tantos votos positivos? (Eu downvoted)
Tim S.

18
Essa é uma ótima resposta, pois tira uma vantagem tola, mas específica, de um aspecto da linguagem BASIC que não é comumente encontrado em outras línguas (especialmente as modernas). Pode não ser o mais popular (o tempo dirá), mas mal consigo ver como é menos interessante do que usar uma constante como __LINE__ ou obter informações de depuração do quadro de pilha atual (como muitas outras respostas atualmente fazem).
Nick

2
Inteligente, mas ficaria desapontado se nada mais terminasse com mais votos do que este.
agweber

35

Java

public class Hello{
    public static void main(String[] args) {
        System.out.println("Hello World, from line "+new Exception().getStackTrace()[0].getLineNumber()+"!");
    }
}

1
Eu prefiroThread.currentThread().getStackTrace()
Cruncher

3
Thread.getStackTrace () chama (new Exception ()) getStackTrace () se chamado no segmento atual, por isso é a mesma coisa.
dhall

1
estranho .... 2x mesma resposta e 2 quantidades upvote diferentes ... (poderia ser usado como fonte de RNG ...) (o mesmo aqui: codegolf.stackexchange.com/a/30058/10801 )
masterX244

@ masterX244 essas duas respostas não são exatamente idênticas; este usa o getLineNumber()método no rastreamento de pilha, enquanto a resposta que você vinculou usa toString()para encontrar o número da linha.
Breakthrough

9
@ masterX244 também vale a pena notar que esta resposta apareceu 2 horas antes. A segunda vez que vejo uma resposta, não é tão interessante quanto a primeira.
primo

30

Perl

close STDERR;
open FOOBAR,">",\$_;


print!warn,'Hello World, from line ',/(\d+)\.$/,'!';

Não é tão curto quanto usar __LINE__, mas talvez mais interessante.

warné uma ferramenta de depuração, que emite uma declaração STDERRindicando em qual arquivo e em qual linha o aviso foi emitido ... a menos que STDERR tenha sido fechado anteriormente ou esteja inacessível, caso em que o aviso será emitido para o arquivo aberto mais recentemente handle - esse é um comportamento não documentado. Não tenho certeza se seria melhor classificado como um recurso ou um bug.

Aqui, STDERRé fechado e um novo identificador de arquivo identificado como FOOBARé aberto e roteado para a variável $_. Isso é analisado para recuperar o número da linha do aviso, incorporado na instrução print.


3
Sim, definitivamente é mais interessante :)
Tal

27

C ++

#include <iostream>
#include <utility>
#include <type_traits>

#define __(A,B,C,...) B##C##A
#define _(A,...) __(__VA_ARGS__, A)
template<unsigned...Is> struct v;
template<unsigned I0, unsigned... Is> struct v<I0, Is...>:v<I0-1,I0-1, Is...> {};
template<unsigned...Is> struct v<0,Is...>:std::integral_constant<unsigned, sizeof...(Is)> {};

int main() {
  std::cout << "Hello world from line " << v<_(EXTRACT,_(Q,_,E,_,$$main$$,),_(@22,,_,_),_(Z,N,L,I,_,,L),__STACK_TRACE__)>::value << "\n";
}

exemplo ao vivo


2
Isto é ... magia
Paladine

1
Levei ... muito tempo para ver como isso funcionava. Tantos arenques vermelhos! Está delicioso.
6/14

1
Então, como isso funciona?
04046060D2

16

Lua

print("Hello world, from line "..debug.getinfo(1).currentline.."!")

16

C #

O C # 5.0 [CallerLineNumber]faz o truque:

using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace LineNumberConsole
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Hello World, from line {0}!", ToRoman(GetLineNumber()));
            Console.ReadLine();
        }

        private static int GetLineNumber([CallerLineNumber] int sourceLineNumber = 0)
        {
            return sourceLineNumber;
        }

        private static string ToRoman(int number)
        {
            // TODO: Copy some source code from http://pastebin.com/w0hm9n5W
            // Skipped here for brevity
            return number.ToString();
        }
    }
}

Saída

Hello World, from line X!

Alguma razão específica para usar algarismos romanos?
Cole Johnson

4
Quando a linha de impressão é a linha 10, a pergunta é interpretada literalmente. Xem algarismos romanos é 10.
Οurous

Algarismos romanos é um toque agradável!
NPSF3000

15

C

#include <stdio.h>
main(){
printf("Hello World, from line %d!", __LINE__);
}

O uso de variáveis ​​definidas como LINE , embora permitido pelas regras, é desencorajado.
vaxquis

@vaxquis, sim, mas minha resposta é anterior à edição da pergunta
gnibbler

ainda é uma solução IMO ruim e óbvia demais . Gostaria de saber por que as pessoas postaram todos os tipos de variações dessa solução em todas as línguas do mundo (incluindo PHP, D, Perl), em vez de tentarem fazer algo remotamente engraçado ou intrigante?
precisa saber é o seguinte

14

Python

Exemplo (10 linhas, 213 caracteres):

import sys
import traceback
lineno = None
while True:
    try:
        print 'Hello World, from line %d!' % lineno
        break
    except:
        lineno = traceback.tb_lineno(sys.exc_info()[2])
        continue

Experimente online aqui . Código e espaço em branco que não alteram o fluxo podem ser adicionados e o programa exibirá a contagem de linhas atualizada e, da mesma forma, esse trecho de código também pode ser usado em qualquer lugar de um programa existente. Saída esperada:

Hello World, from line 6!

Outro exemplo (tente online aqui) para mostrar que funciona quando código / espaço em branco é adicionado. Saída esperada:

Down we go...
Gotta catch 'em all.
Down we go...
Hello World, from line 11!
Awesome!

12

Javascript

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}
//Line 12
console.log ('Hello World, from line ' + getLine(1) + ' !')

Nota: As expressões avaliadas no console do desenvolvedor do chrome serão agrupadas em uma withinstrução Portanto, precisamos diminuir a linha por um, se for esse o caso


2
dat pilha , hehe. Trabalho confirmado no Firefox.
Breakthrough

1
@ Breakthrough :) Sim, ele funciona em vários navegadores (testado apenas com o Chrome, FF, IE mais recente). O Chrome precisa de tratamento especial quando avaliado a partir do console, pois envolve todas as instruções em uma withcláusula.
C5H8NNaO4

2
Nome de usuário interessante, mas ambíguo. Glutamato monossódico, talvez? (BTW, eu estou pensando em fazer uma pergunta sobre DNA e aminoácidos, dos quais o ácido glutâmico é um.) #
Level River St

@steveverrill Segundo o google, você está correto !
kitcar2000

@ kitcar2000 Provavelmente. Mas existem outros compostos menos conhecidos com esta fórmula: metilaspartato de sódio ou nitropentanoato, por exemplo.
Level River St

11

Python 3

import hashlib
with open(__file__) as f:
    line_num = 0
    for line in f.readlines():
        line = line.rstrip() # make it work with or without newline at the end
        line_num += 1
        if hashlib.sha256(bytes(line, "UTF-8")).hexdigest()[0:6] == 'cc46f7':
            print('Hello world, from line {}!'.format(line_num)) # cc46f7

Olá mundo, da linha 8!

Esse código de leitura automática contém um hash de referência própria. A soma SHA256 da última linha (com o espaço em branco inicial e sem espaço em branco à direita) começa com cc46f7... . Quando faz o hash da printlinha, descobre que o hash corresponde ao valor mágico que está procurando.


você não poderia simplesmente definir line_num = como -1 e imprimir fora do loop e pegar o hash mágico?
dave

1
@ não tenho certeza se eu te sigo. O hash mágico é o que torna essa solução inteligente.
Tim S.

+1 para interpretação literal das minhas regras :) Muito esperto.
Breakthrough

5
@ Stefan Este site é sobre as piores práticas, no entanto. ;)
Tim S.

1
@sehe Provavelmente, isso ocorreu devido a problemas de espaço em branco. Eu não tinha uma nova linha no final do arquivo quando o criei. Adicionei uma linha para remover o espaço em branco do final da linha antes do hash. Agora deve funcionar de forma mais consistente. (também verifique se você não está convertendo os espaços em guias) Tentei fazer o upload para ideone para mostrar uma versão ao vivo, mas ele não pode ler seu próprio arquivo lá.
Tim S.

9

GNU COBOL

Bem, eles disseram que não poderia ser feito. Na verdade, fui eu quem disse que não poderia ser feito. Agora está pronto e um recurso de linguagem obsoleta reimplementado usando o método aplicado.

A pergunta afirma:

Se qualquer espaço em branco ou instrução adicional (que não interrompa o fluxo do código) for adicionado ao código-fonte, ele deverá ser refletido no tempo de execução (após a compilação, se aplicável).

Qualquer quantidade de material pode ser inserida antes dos três DISPLAYs que causam o início da saída e qualquer coisa após os DISPLAY"interromperia o fluxo do código", então tudo bem.

O COBOL costumava ter um TRACEverbo (instrução) que simplesmente listava os números das linhas de origem conforme eram executados (sem acesso ao número da linha no programa). Embora de uso limitado, incluí uma implementação do TRACE.

   ID Division.
   Program-ID. HIWHERE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a b
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line "!"
       .
   End Declaratives
       .
   Main-Program Section.
       DISPLAY "Perform"
       Display "Hello World, from line " no advancing Perform b
       display "GO TO"
       Display "Hello World, from line " no advancing GO TO a
       .
   a.
       dISPLay "Fall through"
       Display "Hello World, from line " no advancing. b.
   The-Last-bit-OF-the-PROGRAM.
       GOBACK
       .

A saída é

Perform
Hello World, from line     18!
GO TO
Hello World, from line     20!
Fall through
Hello World, from line     23!

Como uma demonstração do poder e da flexibilidade de escrever a linguagem, este exemplo usa letras maiúsculas, minúsculas e totalmente maiúsculas, tudo ao mesmo tempo. Não importa, pois quando processado, tudo é "dobrado" para MAIÚSCULAS.

A única maneira padrão de COBOL de obter um número de linha de origem no programa em execução, a partir do programa em execução, é com a DEBUGGING DECLARATIVE. Dentro de SECTION, estritamente dentro de um parágrafo dentro de SECTION, de um declarativo, você tem acesso ao registro especial DEBUG-LINE. Contém o número da linha de origem do verbo (instrução) que causou a transferência do controle para um nome de procedimento específico (parágrafo ou SECTION).

Portanto, com PERFORM, ou GO TO, ou "falha", o parágrafo nos declarativos de depuração SECTIONé executado.

OK, mas DISPLAYnão causa transferência de controle.

Sem problemas. Coloque-o na mesma linha da transferência de controle.

Problema, pois se "qualquer espaço em branco ou instrução adicional (que não interrompa o fluxo do código) for adicionado ao código-fonte, ele deverá ser refletido no tempo de execução (após a compilação, se aplicável)".

Portanto, coloque-o na mesma linha, mas na frente de uma transferência de controle, divida o conteúdo do arquivo DISPLAYem duas partes (lembre-se: "Nesse contexto, queremos o primeiro número da linha da instrução que gera a string a ser exibida" ) e produza a primeira parte antes da transferência do controle e a segunda parte do DEBUG-LINE, uma vez dentro do procedimento de depuração.

O truque final é para o "fall through" ("procedures" podem ser PERFORMeditados, podem ser o alvo de um GO TOou podem ser inseridos simplesmente sendo a próxima linha). Nesse caso, coloque o DISPLAY na linha que define o procedimento, mas na frente da definição .

Os nomes dos "procedimentos" ( ae b) foram severamente abreviados para permitir que eles se ajustem à mesma linha de origem que a DISPLAY. Estritamente, um nome de procedimento COBOL deve começar em algum lugar da coluna oito à coluna 11. No entanto, atualmente, a sintaxe é muito mais tranqüila quanto a isso. Na medida em que eu possa definir um nome de procedimento na mesma linha que algum código. Inclusive incorporado no código. É necessário cuidado e um ponto final ocasional.

Em PROCEDURE DIVISIONcada ponto final mostrado é necessário, e não mais.

Compilar:

cobc -x -g hiwhere.cbl

Para executar (linux):

COB_SET_DEBUG=Y ./hiwhere

Finalmente, o retorno do TRACE (sem READY / RESET).

   ID Division.
   Program-ID. tRacE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line
       .
   End Declaratives
       .
   Main-Program Section.
  *    Just append "perform a" to a single-line statement.
       DISPLAY "1" . perform a
       Display "2" . perform a
       display "3" . perform a
  *    Or prepend "perform a." for a multi-line statement, or a
  *    statement which won't "come back". 
       perform a. GOBACK
       .
   a.
       CONTINUE
       .

A saída é:

1
    17
2
    18
3
    19
    20

Onde 1, 2 e 3 são emitidos pelas três instruções DISPLAY, e 17, 18, 19 e 20 são os números de linha das linhas "executáveis" (sem depuração).


8

Java

Usando o comportamento do rastreamento de pilha do Exception para obter a linha atual. contanto que a declaração de impressão não seja mutilada em várias linhas ou o arquivo de classe seja mutilado, deve funcionar

public class PrittLnbr
{
    public static void main(String[] args)
    {
        System.out.println("Hello World, from line "+new Error().getStackTrace()[0].toString().split(":")[1]+"!");
    }
}

8

Python

import traceback, inspect
frame = inspect.currentframe()
print("Hello World, from line "+traceback.format_stack(frame)[0].split()[3][:-1]+"!")  


6

Java

public class HelloFrom {
    public static void main(String[] args) {
        System.out.println("Hello World, from line " + Thread.currentThread().getStackTrace()[1].getLineNumber() + "!");
    }
}

tecnicamente o mesmo que eu fiz ( codegolf.stackexchange.com/a/30058/10801 )
masterX244 3/14

2
Mais ou menos, exceto usando o Thread atual em vez de criar um novo Erro para obter o rastreamento da pilha. Não há qualquer erro;)
Cineris


6

Befunge

Feito apenas por diversão.

>00g1+:00p"v"\10v  
    v-*45g00p\g <  
#v+1_$10g1vv,,,,<  
^<p000p01+<#>,,,^  
>" enil morf ,oll"v
@.,,,,,,,,,<^,"He"<

Condicional: o canto superior esquerdo do código deve ser 0 <x <20 e 0 <= y <62; e as duas primeiras células precisam estar vazias.

exemplo:

                         v                  

                         0                  
                         0                  
                         0                  
                         p                  
                         0                  
                         1                  
                         0                  
                         p                  
                         >00g1+:00p"v"\10v  
                             v-*45g00p\g <  
                         #v+1_$10g1vv,,,,<  
                         ^<p000p01+<#>,,,^  
                         >" enil morf ,oll"v
                         @.,,,,,,,,,<^,"He"<

Saída:

Olá, da linha 10


Não faço ideia do que se tratava, mas acredito que o seu pedido de saída, de modo +1 ;-)
ysap

1
Para aqueles que questionam o poder do poderoso Befunge, testá-lo aqui: quirkster.com/iano/js/befunge.html
Justin

6

C

Usando uma macro variável, podemos criar uma função de impressão que adiciona automaticamente o número da linha ao final de uma instrução arbitrária printf, e sempre imprime no stdout.

test.c:

#include <stdio.h>

#define printfl(format, ...) fprintf(stdout, format " From line %d\n", ##__VA_ARGS__, __LINE__)

int main() {
    printfl("Hello World! I have %d argument(s).", 1);
    return 0;
}

saídas:

% ./test
Hello World! I have 1 argument(s). From line 6

Nota: Eu me desviei do padrão para demonstrar que printfl ainda é uma função variável válida; se você realmente se importa com o formato da saída, sempre pode alterar os literais que eu uso.


Isso funciona apenas se você usar uma seqüência de formato constante. Ele falhará se você passar qualquer outra expressão para a sequência de formato.
Snowbody

5

Bater

#
# some comments to fill some lines...
#
echo "Hello World, from line $LINENO!"

Saída

Hello World, from line 4!

@professorfish ... o que há de errado com o MEU estilo para mostrar MINHA resposta? Você deve pelo menos explicar por que você manipular a minha arte ... :-P

2
eu mudei o código? se eu fiz, me desculpe. Eu estava preocupado que os usuários não festança não seria capaz de dizer qual era o código fonte e qual foi o resultado

1
E todo mundo além de mim adora ver as coisas dele sendo alteradas sem comentar o porquê? Lugar estranho ...

3
Foi basicamente uma correção de formatação. Não há nada realmente errado com aqueles AFAIK

O uso de variáveis ​​definidas como LINE , embora permitido pelas regras, é desencorajado.
vaxquis

5

D

void main ()
{
    import std.stdio;
    writefln("Hello World, from line %d", __LINE__);
}

O uso de variáveis ​​definidas como LINE , embora permitido pelas regras, é desencorajado.
vaxquis

5

C ou C ++ e AWK

lineno.c:

// code or comments
// ....
#error Hello World, from line
// other code or comments

Uso:

gcc lineno.c 2>&1 | awk '{ split($0,a,":"); ; printf("%s %s!\n", gensub(".*#error ","",1), a[2]); exit; }'

Saída:

Olá Mundo, da linha 3

Notas:

  • Nenhum código gravado pelo usuário pesquisa o arquivo.
  • O g ++ funcionará em um arquivo c ++.

4

Tipo de chato em Ruby:

puts "Hello World, from line #{__LINE__}!"

Isso não é trapaça, certo?


Não, isso não é trapaça! Este desafio será, obviamente, muito mais fácil em alguns idiomas e mais difícil em outros, no entanto, que foi por isso que eu postei isso :) (Eu vejo agora por que a inclusão de um critério de pontuação é tão importante)
Breakthrough

O uso de variáveis ​​definidas como LINE , embora permitido pelas regras, é desencorajado.
precisa saber é o seguinte

1
@ vaxquis Sim, essa declaração foi adicionada após esta resposta.
precisa saber é o seguinte

4

Javascript

Uma linha usando rastreamento de pilha.

(function (o) { console.log("Hello World, from line " + (Error.captureStackTrace(o) || o.stack.match(/\d+/)[0] - !!__commandLineAPI) + "!"); })({});

3

Cobra

class Program
    def main
        print 'Hello World, from line [System.Diagnostics.StackFrame(true).getFileLineNumber]!'

3

Rubi

File.write "hello.rb", "x=2\n"+"x+=1\n"*rand(rand(100))+'puts "Hello World, from line #{x}!"'
system "ruby hello.rb"
File.delete "hello.rb"

3

PowerShell

Movimento barato

Function LemmeGetDatError() {
    "Too busy chuggin along"
    "Then all of a sudden, I meet a new programmer"
    "And he's all like"
    Write-Output "$(Try {"Hello World from"; Throw "error" } Catch {$_.ScriptStackTrace.Split(":")[1]})"
}

LemmeGetDatError

3

Powershell

$l=(Get-PSCallStack | ForEach{$_.Location})[0].split(' ')[-1]; "Hello World, from line $l!"

E:

try{ I AM ERROR. } catch { $l=$error[0].InvocationInfo.ScriptLineNumber; "Hello World, from line $l!" }

Ambos funcionam assim:

PS C:\MyFolder> .\helloworld.ps1
Hello World, from line 1!

+1, mas Write-Hostnão escreve para stdout. Basta passar a string para enviá-la ao stdout. Exemplo"Hello World, from line {0}!" -f (gcs| %{$_.ScriptLineNumber})[0]
Rynant

@Rynant Bom ponto! Vou atualizar minhas respostas a considerar que ...
DarkAjax

3

Python

import traceback

print 'Hello World, from line %i!' % traceback.extract_stack()[0][1]

Curto e grosso.


3

Perl

Outro Perl:

use warnings;

$SIG{__WARN__} = sub { ($line = shift) =~ s/\D//g; };

$x=$x+1; print "Hello World, form line $line!\n";
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.