Escriba un fragmento de código para generar el número de línea de la declaración de impresión / salida en sí (en la forma "¡Hola Mundo, desde la línea X!")


25

El reto

Escriba un programa que muestre Hello World, from line X!, donde Xestá el número de línea, en el código fuente, de la declaración de impresión en sí.

Las normas

  • En este contexto, queremos que el primer número de línea de la declaración que emite la cadena que se muestra astdout
  • Debe evitar simplemente buscar a través de su código fuente como una cadena (ya sea archivo o quine) para encontrar el número de línea
  • Si se agrega un espacio en blanco adicional o declaraciones (que no interrumpan el flujo del código) al código fuente, debe reflejarse en tiempo de ejecución (después de la compilación, si corresponde)

Recomendaciones

Si lo proporciona el idioma, puede usar excepciones / seguimientos de pila para lograr este objetivo. Haga todo lo posible para usar código que sea portátil en diferentes sistemas / implementaciones, pero tenga en cuenta que esto no es un requisito. __LINE__Se desaconseja el uso de variables definidas como , aunque lo permiten las reglas.

El ganador

  • Este es un concurso de popularidad (finalizado el 10 de junio de 2014), donde la respuesta más votada por la comunidad será declarada ganadora según los votos actuales en ese momento.

  • Al votar, considere la creatividad de la respuesta de alguien, cuán elaborada o interesante es. y las dificultades / limitaciones del lenguaje de programación utilizado


¿Qué quieres decir con "el número de la primera línea"? ¿Estás hablando de lo que debería pasar si la declaración abarca varias líneas?
user2357112 es compatible con Monica el

@ user2357112 sí, solo para resolver cualquier ambigüedad si alguien necesitara usar una declaración milti-line.
Avance el

El título es muy explícito, pero quizás un poco largo.
primo

1
Las respuestas a esto son aburridas porque es una pregunta muy mala. Es como si el autor de la pregunta no supiera de la existencia de LINE . De hecho, me inscribí específicamente para rechazar este voto, pensé que era muy malo.
Dave

1
@Markasoftware si se agregara una línea antes, la salida no cambiaría para reflejar eso.
primo

Respuestas:


48

Sinclair Basic

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

Hola mundo, desde la línea 10!

Esto funcionará para cualquier línea PEEKingresando a la dirección que almacena el número de línea actual, por lo que lo siguiente también funcionará:

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

Hola mundo, desde la línea 341!


Y de la misma manera, Timex / Sinclair BASIC!
Gabe

No pretendo saber este idioma, pero ¿no puedes dejar de lado STR$si reemplazas los +signos por punto y coma?
Sr. Lister

@ MrLister Sí, eso definitivamente funcionaría, pero siempre uso +s por hábito.
kitcar2000

40

BASIC

Creo que esto hace todo lo que se le pidió:

10 PRINT "Hello World, from line 10!"

55
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). La intención está ahí. Además, esa es la primera línea de la fuente, no la décima.
Bill Woodger

30
Puede ser la primera línea del código fuente, pero sigue siendo la línea 10 .
aprensivo ossifrage

13
Creo que esto cae firmemente en la categoría que ya no es divertida . Es realmente poco imaginativo y poco interesante, aunque literalmente cumple con el requisito. ¿Por qué esto tiene tantos votos a favor? (He votado negativamente)
Tim S.

18
Esta es una gran respuesta porque toma una ventaja tonta pero específica de un aspecto del lenguaje BASIC que no se encuentra comúnmente en otros idiomas (especialmente los modernos). Puede que no sea el más popular (el tiempo lo dirá), pero apenas puedo ver cómo es menos interesante que usar una constante como __LINE__ u obtener información de depuración del marco de pila actual (como lo hacen actualmente la mayoría de las otras respuestas).
Nick

2
Inteligente, pero estaría decepcionado si nada más terminara con más votos a favor 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
PreferiríaThread.currentThread().getStackTrace()
Cruncher el

3
Thread.getStackTrace () llama (nueva Excepción ()). GetStackTrace () si se llama en el hilo actual, por lo que es lo mismo
DHall

1
extraño .... 2 veces la misma respuesta y 2 cantidades diferentes de votos a favor ... (podría usarse como fuente RNG ...) (lo mismo aquí: codegolf.stackexchange.com/a/30058/10801 )
masterX244

@ masterX244 esas dos respuestas no son exactamente idénticas; este usa el getLineNumber()método en el seguimiento de la pila, mientras que la respuesta que vinculaste usa toString()para encontrar el número de línea.
Avance

99
@ masterX244 también vale la pena señalar que esta respuesta apareció 2 horas antes. La segunda vez que veo una respuesta, no es tan interesante como la primera.
primo

30

Perl

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


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

No es tan corto como usarlo __LINE__, pero quizás sea más interesante.

warnes una herramienta de depuración, que emite una declaración para STDERRindicar en qué archivo y en qué línea se emitió la advertencia ... a menos que STDERR se haya cerrado previamente o sea inaccesible, en cuyo caso la advertencia se emite al archivo abierto más recientemente manejar: este es un comportamiento no documentado. No estoy seguro de si estaría mejor clasificado como una característica o un error.

Aquí, STDERRestá cerrado, y un nuevo identificador de archivo identificado como FOOBARabierto, y enrutado a la variable $_. Esto se analiza para recuperar el número de línea de la advertencia, que está incrustado en la declaración de impresión.


3
Sí, definitivamente es más interesante :)
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";
}

ejemplo en vivo


2
Esto es ... magia
Paladine

1
Me tomó un ... mucho tiempo ver cómo funcionaba esto. ¡Tantos arenques rojos! Es delicioso.
Sehe

1
¿Entonces, cómo funciona?
0x499602D2

16

Lua

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

16

DO#

C # 5.0 [CallerLineNumber]hace el truco:

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();
        }
    }
}

Salida

Hello World, from line X!

¿Alguna razón en particular para usar números romanos?
Cole Johnson

44
Cuando la línea de impresión es la línea 10, la pregunta se interpreta literalmente. Xen números romanos es 10.
Precioso

¡Los números romanos son un buen toque!
NPSF3000

15

do

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

Se desaconseja el uso de variables definidas como LINE , aunque lo permiten las reglas.
vaxquis

@vaxquis, sí, pero mi respuesta es anterior a la edición de la pregunta
gnibbler

sigue siendo un pésimo y demasiado obvia solución IMO. Me pregunto por qué las personas publicaron todo tipo de variaciones de esta solución en todos los idiomas del mundo (incluidos PHP, D, Perl) en lugar de tratar de hacer algo remotamente divertido o intrigante.
vaxquis

14

Pitón

Ejemplo (10 líneas, 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

Prueba en línea aquí . Se pueden agregar códigos y espacios en blanco que no alteren el flujo y el programa mostrará el recuento de líneas actualizado, y de la misma manera, este fragmento de código también se puede usar en cualquier parte de un programa existente. Rendimiento esperado:

Hello World, from line 6!

Otro ejemplo (intente en línea aquí) para mostrar que funciona cuando se agrega código / espacio en blanco. Rendimiento esperado:

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: Las expresiones evaluadas desde la consola de desarrollo de Chrome se incluirán en una withdeclaración. Por lo tanto, debemos disminuir la línea en uno si ese es el caso


2
dat stack , jeje. Trabajo verificado en Firefox.
Avance

1
@Breakthrough :) Sí, funciona en varios navegadores (aunque solo se probó con el último Chrome, FF, IE). Chrome necesita un tratamiento especial cuando se evalúa desde la consola, ya que envuelve cada declaración en una withcláusula.
C5H8NNaO4

2
Nombre de usuario interesante pero ambiguo. ¿Glutamato monosódico, tal vez? (Por cierto, estoy pensando en hacer una pregunta sobre el ADN y los aminoácidos, de los cuales el ácido glutámico es uno.)
Level River St

@steveverrill Según google, ¡ tienes razón !
kitcar2000

@ kitcar2000 Probablemente. Pero hay otros compuestos menos conocidos con esta fórmula: metilapartato de sodio o nitropentanoato, por ejemplo.
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

Hola mundo, desde la línea 8!

Este código de lectura automática contiene un hash de referencia automática. La suma SHA256 de la última línea (con el espacio en blanco inicial y sin espacio en blanco final) comienza con cc46f7... . Cuando printaplica el hash a la línea, descubre que el hash coincide con el valor mágico que está buscando.


¿No podría simplemente establecer line_num = a -1 y tener la impresión fuera del bucle y obtener el hash mágico?
Dave

1
@ No estoy seguro de seguirte. El hash mágico es lo que hace que esta solución sea inteligente.
Tim S.

+1 para la interpretación literal de mis reglas :) Muy inteligente.
Avance el

55
@Stefan Sin embargo, este sitio trata sobre las peores prácticas. ;)
Tim S.

1
@sehe Lo más probable es que esto se deba a problemas de espacios en blanco. No tenía una nueva línea al final del archivo cuando lo hice. He agregado una línea para eliminar espacios en blanco desde el final de la línea antes del hash. Debería funcionar de manera más consistente ahora. (también asegúrese de no convertir los espacios en pestañas) Intenté subirlo a ideone para mostrarle una versión en vivo, pero no puede leer su propio archivo allí.
Tim S.

9

GNU COBOL

Bueno, dijeron que no se podía hacer. En realidad, fui yo quien dijo que no se podía hacer. Ahora está hecho, y una característica de lenguaje obsoleta se volvió a implementar utilizando el método aplicado.

La pregunta dice:

Si se agrega un espacio en blanco o declaraciones adicionales (que no interrumpen el flujo del código) al código fuente, debe reflejarse en tiempo de ejecución (después de la compilación, si corresponde).

Se puede insertar cualquier cantidad de cosas antes de los tres DISPLAYs que causan el inicio de la salida, y cualquier cosa después de los DISPLAYs "interrumpiría el flujo del código", entonces está bien.

COBOL solía tener un TRACEverbo (enunciado) que simplemente enumeraba los números de línea de origen a medida que se ejecutaban (sin acceso al número de línea en el programa). Aunque de uso limitado, he incluido una implementación de 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
       .

La salida es

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

Como una muestra del poder y la flexibilidad de escribir el lenguaje, este ejemplo utiliza mayúsculas y minúsculas y mayúsculas, todo al mismo tiempo. No importa, ya que cuando se procesa, todo se "dobla" a MAYÚSCULAS.

La única forma estándar de COBOL de obtener un número de línea de origen en el programa en ejecución, desde el programa en ejecución, es con un DEBUGGING DECLARATIVE. Dentro de un SECTION, estrictamente dentro de un párrafo dentro de unSECTION , de tal declaración tiene acceso al registro especial DEBUG-LINE. Contiene el número de línea de origen del verbo (instrucción) que causó la transferencia del control a un nombre de procedimiento particular (párrafo o SECTION).

Entonces, con PERFORM , o GO TO, o "caer" el párrafo en las declaraciones de depuración SECTIONse ejecuta.

Bien pero DISPLAY no causa transferencia de control.

No hay problema. Ponlo en la misma línea que la transferencia de control.

Problema, ya que si "cualquier espacio en blanco adicional o declaraciones (que no interrumpan el flujo del código) se agrega al código fuente, debe reflejarse en tiempo de ejecución (después de compilar si corresponde)".

Por lo tanto, colóquelo en la misma línea pero frente a una transferencia de control, divida el contenido de la misma DISPLAYen dos partes (recuerde: "En este contexto, queremos que se muestre el primer número de línea de la instrucción que genera la cadena" ) y muestra la primera parte antes de la transferencia de control, y la segunda parte, desde DEBUG-LINE, una vez dentro del procedimiento de depuración.

El último truco difícil es para la "caída" (los "procedimientos" pueden ser PERFORMeditados, pueden ser el objetivo de un GO TO, o pueden ingresarse simplemente siendo la siguiente línea). En este caso, pon elDISPLAY en la línea que define el procedimiento, pero delante de la definición .

Los nombres de los "procedimientos" ( ay b) se han acortado severamente para permitir que quepan en la misma línea de origen que elDISPLAY . Estrictamente, un nombre de procedimiento COBOL debe comenzar en algún lugar de la columna ocho a la columna 11. Sin embargo, la sintaxis es, en estos días, mucho más relajada al respecto. En la medida en que pueda definir un nombre de procedimiento en la misma línea que algún código. Incluso incrustado en el código. Se requiere cuidado y, ocasionalmente, una parada completa.

En el PROCEDURE DIVISION cada punto completo que se muestra se requiere, y no más.

Compilar:

cobc -x -g hiwhere.cbl

Para ejecutar (linux):

COB_SET_DEBUG=Y ./hiwhere

Finalmente, el retorno de TRACE (sin 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
       .

Salida es:

1
    17
2
    18
3
    19
    20

Donde 1, 2 y 3 salen de las tres declaraciones DISPLAY, y 17, 18, 19 y 20 son los números de línea de las líneas "ejecutables" (sin depuración).


8

Java

Usar el comportamiento del seguimiento de pila de Exception para obtener la línea actual. siempre y cuando Printstatement no esté destrozado en varias líneas o el archivo de clase se destruya, debería 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

Pitón

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

6

Perl

print 'Hello World, from line '.__LINE__.'!';

13
Esta también es una solución PHP válida.
MrLore

6

Java

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

técnicamente igual que yo ( codegolf.stackexchange.com/a/30058/10801 )
masterX244

2
Más o menos, excepto usar el hilo actual en lugar de crear un nuevo error para obtener el seguimiento de la pila. No hay ningún error;)
Cineris

6

Pitón

import inspect
print ("Hello world from line %d!" % (inspect.getlineno(inspect.currentframe())))

Salida

Hello World from line 2!

1
¡El mejor Python hasta ahora!
kirbyfan64sos

6

Befunge

Hecho solo por diversión.

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

Condicional: la parte superior izquierda del código debe ser 0 <x <20 y 0 <= y <62; y las dos primeras celdas deben estar vacías.

ejemplo:

                         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"<

Daría salida:

Hola desde la linea 10


Ni idea de lo que era, pero creo que su demanda de salida, por lo ;-) 1
ysap

1
Para aquellos que cuestionan el poder de Befunge poderoso, pruébelo aquí: quirkster.com/iano/js/befunge.html
Justin

6

do

Mediante el uso de una macro variable, podemos hacer una función de impresión que agrega automáticamente el número de línea al final de una declaración de impresión arbitraria, y siempre imprime en stdout.

prueba.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;
}

salidas:

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

Nota: Me desvié del patrón para demostrar que printfl sigue siendo una función variable válida; Si realmente te importa el formato de la salida, siempre puedes cambiar los literales que uso.


Esto solo funciona si usa una cadena de formato constante. Falla si pasa cualquier otra expresión para la cadena de formato.
Snowbody

5

Golpetazo

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

Salida

Hello World, from line 4!

@professorfish ... ¿qué tiene de malo MI estilo para mostrar MI respuesta? Al menos deberías explicar por qué manipulas mi obra de arte ... :-P

2
¿Cambié el código? Si lo hice, lo siento. Solo me preocupaba que los usuarios que no son bash no pudieran decir cuál era el código fuente y cuál era la salida

1
Y a todos los demás, además de mí, les encanta ver que cambian sus cosas sin comentar por qué. Lugar extraño ...

3
Básicamente fue una solución de formato. No hay nada realmente malo con esos AFAIK

Se desaconseja el uso de variables definidas como LINE , aunque lo permiten las reglas.
vaxquis

5

re

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

Se desaconseja el uso de variables definidas como LINE , aunque lo permiten las reglas.
vaxquis

5

C o C ++ y 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; }'

Salida:

Hola mundo, desde la línea 3

Notas:

  • Ningún código escrito por el usuario busca el archivo.
  • g ++ funcionará en un archivo c ++.

4

Tipo de aburrido en Ruby:

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

Esto no es trampa, ¿verdad?


No, esto no es trampa! Obviamente, este desafío será mucho más fácil en algunos idiomas y más difícil en otros, sin embargo, por eso lo publiqué :) (Ahora veo por qué es tan importante la inclusión de un criterio de puntuación)
Avance

Se desaconseja el uso de variables definidas como LINE , aunque lo permiten las reglas.
vaxquis

1
@vaxquis Sí, esa declaración se agregó después de esta respuesta.
Ajedi32

4

Javascript

Una línea usando el seguimiento de pila.

(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

Rubí

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

Potencia Shell

Movimiento 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

Potencia Shell

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

Y:

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

Ambos funcionan así:

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

+1, pero Write-Hostno escribe en stdout. Simplemente pasando la cadena lo enviará a stdout. Por ejemplo"Hello World, from line {0}!" -f (gcs| %{$_.ScriptLineNumber})[0]
Rynant

@Rynant Buen punto! Actualizaré mis respuestas para considerar que ...
DarkAjax

3

Pitón

import traceback

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

Corto y dulce.


3

Perl

Otro Perl:

use warnings;

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

$x=$x+1; print "Hello World, form line $line!\n";
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.