Suppression d'une ligne vide dans le code source qui entraîne des fonctionnalités inattendues [fermé]

38

Ecrivez un script qui fonctionne correctement lorsqu'une ligne vide est présente dans le flux de la logique du programme, mais rompt ou provoque un comportement inattendu lorsque cette ligne est supprimée.

Évitez les échappatoires habituelles et les réponses stupides. Votre programme devrait faire quelque chose "d'utile", même s'il ne fait qu'ajouter quelques entiers.

La suppression d'une ligne vide d'une chaîne multiligne ne compte pas, sauf si la sortie attendue de cette chaîne multiligne ne doit pas techniquement changer (c'est-à-dire: si vous supprimez toutes les lignes vides correspondantes ^$).

La stupidité des blancs n'est pas autorisée non plus; ne faites pas de choses étranges avec des retours à la ligne, des tabulations, des espaces, etc.

Naftuli Kay
la source
11
Je pense que vous devriez exclure les espaces.
nneonneo
17
Je pense que Whitespace est une " échappatoire standard "
core1024
5
Nneonneo parle de Whitespace , un langage qui n’utilise que des espaces comme syntaxe.
Kyle Kanos
4
"fonctionnalité inattendue" est une très bonne phrase.
Kaz
3
Je vote pour fermer cette question comme hors sujet, car les défis sournois ne sont plus sur le sujet sur ce site. meta.codegolf.stackexchange.com/a/8326/20469
cat.

Réponses:

62

Javascript

Ouvre une alerte avec "Hello, World!" si la ligne vide existe, sinon, alerte "0".

(function(){
    alert(~(arguments.callee+[]).indexOf('\n\n') && "Hello, World!");

})();

Démo

Explication:

arguments.callee est une référence à la fonction anonyme à exécution automatique.

L'ajout d'un tableau vide ( []) convertit la fonction en chaîne, ce qui vous donne son code source.

indexOfretourne -1si la chaîne n'est pas trouvée.

Effectuer une opération bitwise not operation ( ~) aboutit à -1une transformation en 0valeur de falsey.

Nderscore
la source
2
C'est quoi cette supercherie?!
Kroltan
1
arguments.calleecontient la source de la fonction.
Matthew
2
Notez que cela ne fonctionne plus en mode strict (ce que le code le plus moderne utiliserait). Le mode strict interdit l'utilisation de arguments.callee.
Daniel Lo Nigro
1
@ Michael: Non, spec ne dit rien sur le format exact. En fait , il existe des moteurs qui ne préservent pas les espaces.
Bergi
2
@DanielLoNigro Vous pouvez simplement donner un nom à l'expression de fonction et l'utiliser à la place de arguments.callee. Même le rend plus court.
Un chat
42

C

Ce programme magique à 8 balles fonctionnera toujours sans la ligne blanche, mais il sera un peu plus décisif - aucune des réponses neutres n'apparaîtra jamais dans la sortie.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
  int x, t;
  char *quotes[] = {
        // Positive :-)
        "It is certain", "It is decidedly so", "Without a doubt", "Yes definitely", "You may rely on it",
        "As I see it, yes", "Most likely", "Outlook good", "Yes", "Signs point to yes",
        // Indifferent :-\

        "Reply hazy try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again",
        // Negative :-(
        "Don't count on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful" };
  srandom(time(NULL)); // Initialize random number generator
  x = random() % (sizeof(quotes) / sizeof(char*)); // Choose a random outcome
  printf("The Magic Eight Ball says...\n%s\n",quotes[x]);
  return 0;
}

Explication

Lorsque l'analyseur C voit une barre oblique inversée suivie d'un caractère de nouvelle ligne, il ignore les deux et traite la deuxième ligne comme une continuation de la première. Sans la ligne vide, les réponses "indifférentes" seront toutes traitées dans le cadre du commentaire précédent.

ossifrage délirant
la source
51
I + 1'd, mais voir les commentaires C se terminer par une barre oblique inverse commence à devenir une échappatoire standard, IMO.
Tim S.
2
C'était une référence à cet article "d'échappatoire standard" , alors peut-être pas littéralement une "échappatoire".
Tim S.
5
@TimS. si vous vous ennuyez avec cette "solution", pourquoi avez-vous voté?
John Dvorak
8
Les réponses de la barre oblique inverse la prochaine ligne dans un commentaire (trigraphe ou pas de trigraphe) me font souhaiter que j'avais 125 points de réputation. Je continue à les voir et ils commencent à être terriblement répétitifs, totalement transparents, et non plus intelligents ou amusants. (Ce qui est regrettable pour ceux qui les utilisent, comme ceux qui craignent ici, car ils ne méritent absolument pas la colère et sont parfois totalement inconscients de cela - mais le truc c'est de gagner.)
doppelgreen
4
@Jan commence à devenir standard n’est pas la même chose que long-standard / overdone ... son utilisation est assez intelligente ici, elle n’a pas l’ air déplacée (contrairement à certaines de celles que j’ai vues, qui ont inexplicablement un caractère (s) à la fin d'un commentaire, ou terminez leurs commentaires avec le (s) personnage (s) du début du commentaire afin de faire quelque chose d'inhabituel). Donc: je passe à la solution, pas à l'utilisation continue de son astuce.
Tim S.
37

Befunge-93

v
&
&
+
#

.
@

Mon premier programme befunge :)

Il lit deux nombres à partir de l'entrée et affiche leur somme. Si vous supprimez la ligne vide, cela n’imprimera rien.

Explication:

v définit une direction descendante pour l'exécution du code
& lit un entier
+ajoute les nombres ensemble
#saute la commande suivante
.imprime un entier de la pile
@ termine le programme

Comme écrit, #saute la ligne vide et contine avec .. Achetez lorsque vous supprimez la ligne vide,. est ignorée.

Il semble y avoir un bon interprète à http://befunge.aurlien.net/

Aditsu
la source
Ah, intelligent.
seequ
1
Befunge 98 le fait également. Bien pensé. Et cet interprète a quelques avantages (je n'ai pas beaucoup utilisé le vôtre, donc je ne connais pas ses avantages).
Justin
32

Rubis / Coquille

​​​​​​
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!   The Amazing Integer Adder             !
#! Adds 1 and 1, and displays the result   !
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

p 1+1

Fonctionne bien si une nouvelle ligne est en haut, sinon la première ligne de commentaire est interprétée par le shell comme un shebang mal formé.

histocrate
la source
3
Cela ne fonctionnerait-il pas toujours ou ne fonctionnerait-il pas toujours? Par exemple, si vous l'utilisiez comme suit ruby youranswer.rb, il ne chercherait pas un shebang car il est déjà utilisé dans l'interpréteur ruby, mais si vous l'utilisiez comme ./youranswer.rbs'il ne s'exécutait pas du tout car il n'y avait pas de shebang ..
Réintégrez Monica
6
Au moins avec mon ruby, le shebang est respecté même si vous l'exécutez en tant que ruby youranswer.rb, ce qui peut être utile pour définir les commutateurs de ligne de commande nécessaires dans le fichier. Donc sans la nouvelle ligne je reçoisruby: no Ruby script found in input (LoadError)
histocrat
29

Scala

case class IntWrapper(i: Int)

{
  val answer = (IntWrapper(0) /: (1 to 100)){(x, y) => IntWrapper(x.i + y)} // Add up ints
  println(s"Sum of wrapped integers is $answer")
}

Si vous supprimez la ligne vierge, aucune sortie ne sera imprimée. Ce qui est pour le mieux, car votre pile déborderait si vous appeliez réellement IntWrapper.

Il s'agit d'un cas d'angle de l'inférence de point-virgule de Scala. Normalement, les nouvelles lignes reçoivent un point-virgule lorsque le code résultant est valide. Cependant, les développeurs de Scala ne voulaient pas forcer les gens à utiliser des crochets égyptiens , il est donc valide de mettre les crochets d'une définition de classe sur la ligne immédiatement après - aucun point-virgule n'est ajouté, bien qu'il puisse l'être. Cependant, une ligne vide sépare les crochets de la définition de classe. Lorsque la ligne vide est supprimée, le code cesse d’être une définition de classe et un bloc pour devenir une définition de classe avec un constructeur - et un constructeur récursif en plus!

James_pic
la source
6
Très gentil de leur part de ne pas forcer les brackets égyptiens. Mais, à mon avis, l’inférence par un point-virgule est une mauvaise idée.
Almo
L'inférence de point-virgule a mauvaise réputation, principalement à cause de JavaScript. C'est un peu moins pénible si vous concevez le langage en gardant à l'esprit (personne ne s'en plaint en Python, par exemple). Malheureusement, Scala a inclus quelques fonctionnalités qui ne jouent pas bien avec l'inférence de point-virgule. Il y a ceci, et les opérateurs postfixes (que j'ai été tenté d'utiliser dans ma réponse, mais c'est un peu dépassé).
James_pic
2
@ James_pic: Autant que je sache, personne ne s'en plaint en Python, car il n'existe pas en Python. Dans JS, les points-virgules sont une partie nécessaire de la syntaxe et peuvent être insérés (inférés) à certains moments. En Python, les points-virgules ne font pas partie de la syntaxe, mais peuvent être utilisés facultativement. C'est une grande différence.
Mason Wheeler
Cela peut sembler être une grande différence, mais si Scala supprimait quelques fonctionnalités qui rendent actuellement les limites des déclarations ambiguës, elles passeraient du côté JavaScript à celui de Python.
James_pic
1
@James_pic: Ce qui différencie python, c'est que newline termine l'instruction, sauf en cas d'échappée ou à l'intérieur de tout type de crochet. C'est qu'il n'y a pas de règle complète / incomplète.
Jan Hudec
27

GolfScript

~{.@\%:

}do;

Calcule le GCD de deux entiers non nuls. Le retrait de la ligne vide interrompt le programme.

Essayez-le en ligne.

Comment ça marche

Ceci est une implémentation GolfScript de l'algorithme Euclidien:

      # STACK: "15 24"
~     # Interpret the input string.
{     # STACK: 15 24
  .@  # Duplicate the topmost integer and rotate the other on top of both copies.
      # STACK: 24 24 15
  \   # Swap the topmost integers.
      # STACK: 24 15 24
  %   # Calculate the modulus.
      # STACK: 24 15
}do   # If the modulus is non-zero, repeat the loop.
;     # Discard the last modulus.

Il y a juste un petit problème:

{}doaffiche le module de la pile pour vérifier s'il est vrai, il doit donc être dupliqué à la fin de la boucle. Ceci est normalement accompli par ., mais :\n\na le même effet: il stocke l’élément de pile le plus haut dans la variable LF (:\n ), puis pousse le contenu de cette variable.

Dennis
la source
7
Wow, même si c'est une variable? : O
Aditsu
@aditsu: Only #, {et }ne peut pas être utilisé comme nom de variable car il fait partie de la syntaxe. Tout autre jeton est bon, y compris les chaînes.
Dennis
@ Dennis wow. Même les chaînes de caractères TIL peuvent être utilisées comme variables. Est-ce utile pour quelque chose?
John Dvorak
@JanDvorak: Mis à part certains cas (code palindromique, code sous - jacent , probablement pas. Je pense que c'est simplement un effet secondaire ( documenté ) de la façon dont l'interpréteur GolfScript divise le code en jetons.
Dennis
@ Dennis cela signifie-t-il que .:-1stocke l'entrée dans -1, pas le signe moins lui-même? Hmm ...
John Dvorak
23

Syntaxe du modèle MediaWiki

Définir le modèle: Foo comme

{{{a

b|Uh-oh!}}}

Dans une autre page,

{{Foo|a

b=Works!}}  <!-- outputs "Works!" -->

{{Foo|a


b=Works!}}  <!-- outputs "Uh-oh!" -->

{{Foo|a
b=Works!}}  <!-- outputs "Uh-oh!" -->

Dans MediaWiki, les noms de paramètres peuvent contenir des nouvelles lignes.

Ypnypn
la source
1
Bien, c'est dans le sens de ce que je cherchais, des cas étranges comme celui-ci.
Naftuli Kay
16

LaTeX (backref)

Le code LaTeX suivant utilise une citation et la citation contient une liste de pages, où l'entrée est citée. Ici c'est la première page. Le package hyperrefajoute également des liens PDF, la référence de page précédente est rouge, le lien de citation est vert.

\documentclass{article}
\usepackage[colorlinks,pagebackref]{hyperref}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.

\end{thebibliography}
\end{document}

Result

Mais LaTeX ne nécessite pas la ligne vide, la ligne vide semble superflue et l'exemple fonctionnera toujours sans hyperrefet la ligne vide:

\documentclass{article}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.
\end{thebibliography}
\end{document}

Result without hyperref

Mais les liens et les références arrières ont disparu, nous les réinsérons donc:

\documentclass{article}
\usepackage[colorlinks,pagebackref]{hyperref}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.
\end{thebibliography}
\end{document}

Mais maintenant, l'exemple est cassé et ne compilera plus:

Runaway argument?
 Donald E. Knuth: \textit {The \TeX book}; Addison Wesley, 1984. \end \ETC.
! File ended while scanning use of \BR@@bibitem.
<inserted text> 
                \par 
<*> knuth

?

Qu'est-il arrivé? Le paquetage hyperref(ou le paquetage plus précis backrefchargé par hyperref) veut aller à la fin de l'entrée de bibliographie pour ajouter la liste de références arrière. Mais la syntaxe dans LaTeX ne fournit que le début de l'entrée \bibitem, la fin peut être n'importe où. Dans ce paquet d'urgence, backrefune restriction a été ajoutée, qui \bibitemdoit se terminer par une ligne vide. Ensuite, le paquet peut redéfinir\bibitem pour mettre les références arrières à la fin de l'entrée.

Comme la ligne vide est manquante, TeX continue à la rechercher, mais a plutôt trouvé la fin du fichier et a généré le message d'erreur.

Heiko Oberdiek
la source
12

C (semi-obscurcie)

Ce petit programme prend un numéro sur la ligne de commande et calcule sa factorielle. Cependant, il contient également une fonctionnalité avancée d'intelligence artificielle permettant de vérifier, à l'exécution, que les normes de codage de la société, notamment l'utilisation correcte des espaces et des lignes vierges, sont respectées. La suppression d'une ligne vide déclenchera l'algorithme pour rejeter le programme insuffisamment maintenable.

Pas de continuations de lignes ou de trigraphes n'importe où. Je crois que c'est valide ANSI C99.

En raison des mathématiques avancées impliquées, si vous compilez avec gcc, pensez à utiliser -lm.

#include <setjmp.h>
#include <stdio.h>
#define max(x,y) ((x<y?y:x))
#define swap(x,y) ((x^=y,y^=x,x^=y))
#include <stdlib.h>
#include <math.h>
#define vfry(x,p,z,y,i) (!!y&((z##z##L##I##p##x##z##z)))
#define NDEBUG

/* 
 * Proper use of whitespace is essential!
 * Please do not remove any blank lines.
 */

const double E = 2.71828182845904523536;

int vrfy(double epsilon, int magic, const char *key, long int L) {
  /* You are not expected to understand this */
  double x=284.2891,u=2.34e56;
  while (rand()+magic*pow(epsilon,sin(x-E))!=log(u*L))
    x*=vrfy(1.0/epsilon,(int)u,&key[swap(L,magic)],L++);
  return u/lgamma(x);
}

int main(int argc, char *argv[]) {
  int N_=831293812; /* do not change, see Knuth 1987 */
  if (!vfry(E, N,_, "M=&;VT=I!9", 0xfe86ddcaL)) {
    fprintf(stderr, "Code standards violation detected!\n");
    abort();
  }
  if (argc < 2) {
    fprintf(stderr, "Usage: %s n\nComputes n!\n", argv[0]);
    exit(1);
  }
  int m=1, n=atoi(argv[1]), i;
  for (i=1; i <= n; i++)
    m *= i;
  printf("%d! = %d\n", n, m);
  return 0;
}

Becquet

La vrfyfonction compliquée n'est jamais appelée, mais plutôt la vfrymacro drôle . L'utilisation de la fonction de concaténation de chaînes du préprocesseur dissimule le fait que nous vérifions simplement la parité de __LINE__.

Nate Eldredge
la source
Fonctionne également avectcc -run
Vi.
C'est vraiment chouette. Ce vfryn'est pas développé dans la définition de la fonction m'a vraiment bouleversé.
FUZxxl
11

C

Ce programme fonctionne comme prévu (comme décrit dans les commentaires) à moins que la ligne vide avant foo = 5; soit supprimée.

Malheureusement, j'ai rencontré une fois une erreur presque identique à celle-ci dans le code de production.

#include <stdio.h>

int main()
{
    int foo = 0;

    #define FROB(x) do {                                            \
        x++;                                                        \
        printf("%d\n", x);                                          \
    } while (0);                                                    \

    foo = 5;
    FROB(foo); /* prints 6 */
    FROB(foo); /* prints 7 */
    FROB(foo); /* prints 8 */

    return 0;
}

Cet exemple utilise l' do { ... } while (0)idiome utilisé pour créer une instruction multiligne dans une macro (voir https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for ). Il utilise également le caractère barre oblique inverse pour répartir #defineplusieurs lignes bien alignées, à l’abri des regards. Cependant, il fait aussi deux choses qui ne vont pas:

  • Il y a un point-virgule après while (0), alors que l'idiome l'oublie généralement
  • Il y a une barre oblique inverse après la dernière ligne du #define

Lorsque cela est en place, la suppression de la ligne vide avant foo = 5;entraîne l'exécution de cette affectation après le printf, mais également après chaque appel de la FROBmacro. En conséquence, le résultat après la suppression de la ligne vide est:

1
6
6
Greg Hewgill
la source
1
En gros, une copie de codegolf.stackexchange.com/a/31662/20356
seequ
@TheRare Mais c'est moins évident.
Ypnypn
6
Ce n'est que moins évident si vous ne regardez pas ces barres obliques inverses très nettement à droite. (Mais comme ils flottent très visiblement sur la droite, ils vont se faire regarder.)
doppelgreener
3
Cependant, tous sauf un sont justifiés
QuadmasterXLII
6
@QuadmasterXLII, techniquement, ils sont tous justifiés - justifiés à droite, pour être précis.
Mark
9

C / C ++

int main(){

    return __LINE__ - 3;
}

Renvoie le succès et peut être utilisé comme une implémentation de true . Si la ligne vide est supprimée, vous pouvez plutôt l'utiliser comme implémentation pour false .

nwp
la source
8

PowerShell

Cette fonction ajoutera deux nombres.

function add ($a, $b) {
    $numbers = @($a `

            $b)
        $numbers| measure -sum| select -expand sum
}

Si vous supprimez la ligne vide, la fonction échouera avec: Unexpected token '$b' in expression or statement.

Explication

Les éléments de tableau peuvent être séparés par des nouvelles lignes et / ou des virgules. Placer le caractère de continuation de ligne ( `) après $anécessite une nouvelle ligne à séparer $aet $b. Sinon, l'interprète considère le code comme $numbers = @($a $b)(aucun séparateur d'élément).

Rynant
la source
7

Texas

\noindent\everypar{$\bullet$ hello }

world
\bye

Sans la ligne vide, "bonjour" n'est pas imprimé.

Explication

TeX traite la ligne vide comme un saut de paragraphe et \everyparest exécuté au début d'un nouveau paragraphe.

Stephan Lehmke
la source
6

Java

import java.util.Scanner;

public class BlankLine
{
    public static void main( String[] args )
    {
        //This calculates 2^ given number
        //if you remove blank line after the next line it will always print 1
        int x = new Throwable().getStackTrace()[0].getLineNumber();

        int y = new Throwable().getStackTrace()[0].getLineNumber() - x;
        System.out.println("Number:");
        Scanner scanner = new Scanner(System.in);
        int r = 1;
        int n = scanner.nextInt();

        for(int i = 0; i < n; i++){
            r *= y;
        }
        System.out.println("2^number: "+r);
    }
}

x est le numéro de ligne actuel, y est le numéro de ligne actuel - x. S'il y a une ligne blanche entre eux, le résultat est 2. Le code calcule donc 2 ^ nombre.

barteks2x
la source
1
+1 simplement parce que c'est Java, bien qu'en tant que visiteur fréquent de Code Review, je me demande pourquoi vous n'utilisez pas Math.pow?
Simon Forsberg
Parce que mon code doit faire quelque chose. Ajouter 2 nombres est un peu trop simple.
barteks2x
Utiliser Math.powet imprimer le résultat, c'est aussi faire quelque chose, n'est-ce pas?
Simon Forsberg
Et maintenant je me suis rendu compte que je pouvais vraiment utiliser .Math.pow Je ne sais pas pourquoi je pensais que je devais le faire de cette façon ... Matbe Je voulais le faire de façon plus "sournoise".
barteks2x
7
Vous avez trop joué au golf. Vous devriez plutôt visiter Code Review où nous faisons les choses correctement!
Simon Forsberg
6

Perl 5

print(<<""
Hello, World!

);

Ce code imprime Hello, World! . La suppression de la ligne vide génère une erreur de syntaxe.

Explication:

La syntaxe Per- here-doc pour les chaînes multilignes autorise une chaîne de terminaison vide. C'est même explicitement documenté. Si vous supprimez la ligne vide, la parenthèse fermante (et tout le reste jusqu'à la ligne vide suivante, le cas échéant) sera interprétée comme faisant partie de la chaîne, ce qui provoquera une erreur de syntaxe.

Les messages d'erreur que vous recevez sont en réalité assez corrects, pour une telle fonctionnalité de syntaxe bizarre. S'il n'y a aucune ligne blanche dans le programme après leprint(<<"" ligne, Perl dit simplement:

Impossible de trouver la terminaison de chaîne "" avant EOF à la ligne 1 de foo.pl.

S'il y a une ligne vide à la fin du programme, vous obtenez quelque chose comme ceci:

erreur de syntaxe à la ligne 4 de foo.pl, à EOF
  (Peut-être une chaîne multiligne << emballée à partir de la ligne 1)
L'exécution de foo.pl a été interrompue en raison d'erreurs de compilation.

Ilmari Karonen
la source
5

Lot

@echo off
setLocal enableDelayedExpansion
set NL=^


echo Hello!NL!World

Ce code sera affiché Helloet sur la ligne suivante World. Lorsque l'une ou les deux lignes vides sont supprimées, rien ne s'affiche.

Il y a une explication ici .

dépouiller
la source
4

Rubis

La suppression de la première ligne provoquera une erreur:

line = IO.readlines($0).first.chomp if line.empty? puts 34+4 else raise "Please add a newline at the beginning of the program." end
Mhmd
la source
2
J'adore le message d'erreur. J'aimerais voir la réaction de quelqu'un qui essaie d'exécuter le programme et obtient cette réponse.
Tomsmeding
4

Python

Je ne sais pas si cela tombe sous les échappatoires habituelles, j'ai regardé la liste et je ne l'ai pas vu.

src = open(__file__, 'r')
code = src.readlines()
src.close()

if code[3] == '\n':
    print 'Hello World!'

En cours d'exécution, cela revient régulièrement

Hello World!

L'exécuter sans la ligne blanche sur la ligne 4, c'est-à-dire comme ci-dessous:

src = open(
__file__, 'r')
code = src.readlines()
src.close()
if code[3] == '\n':
    print 'Hello World!'

ne renvoie rien.

Zaxvo
la source
3

Python 2.x

Ce programme génère le cinquième caractère de la chaîne entrée.

import inspect

text = raw_input()
print 'Fifth character of the string:', text[inspect.getlineno(inspect.currentframe())]

Ce n'est en aucun cas caché. Si vous supprimez la ligne vide, cela donne le quatrième caractère et le sixième si vous en ajoutez un.

voir
la source
3

Tcl

Une fonction qui ajoute deux nombres (et vérifie si la nouvelle ligne a été supprimée):

proc add {a b} {
    if {[llength [split [info body add] \n]] < 5} {error "function has been modified"}

    return [expr $a+$b]
}

Il n'y a rien à cacher ici, il fait ce qu'il dit, donc je n'exploite pas l'explication. La fonction infoest un couteau suisse d'introspection (que d'autres langages appellent la réflexion). info bodyrenvoie le code source d'une fonction (s'il n'est pas écrit en C ou en assembleur).

Je dois admettre que cela m'a stoppé jusqu'à ce que j'ai vu la solution javascript.

bûcheron
la source
3

C

#include <stdio.h>


int main() {
    const char* a = "You love blank lines.";
    #define print_out(a) \

    printf("%s\n", a);
    a = "You don't seem to love blank lines";
    print_out(a);
    return 0;
}

Avec la ligne vide, aest la variable locale a et sans c'est le paramètre macro ...

urzeit
la source
3

Techniquement, ce n'est pas un problème de "code", mais un problème de serveur. Si cela est envoyé à Apache à partir d'un script CGI (qui peut être généré avec n'importe quelle langue de votre choix), il enverra une réponse HTTP au client:

HTTP/1.x 200 OK 
Content-Type: text/html; charset=UTF-8

Hello world!

D'autre part, cela échouera car il manque l'espace vide après l'en-tête.

HTTP/1.x 200 OK 
Content-Type: text/html; charset=UTF-8
Hello world!
Cwallenpoole
la source
2

JavaScript

La fonction whereamirépond avec la position de la ligne appelante, par rapport à sa propre position dans le code source.

console.log (whereami ()) //3 line(s)  before me 


function whereami () {
    var a=function a(e){try{to}catch(c){for(var d=c.stack.split("\n"),b=0;b<d.length&&!~d[b].indexOf("a");b++);return c.stack.split("\n")[b+~~e].match(/:(\d+)/)[1]-~~window.hasOwnProperty("__commandLineAPI")}},a1=a(1),i


    i= a(2)>a(1)+4?a(1):a(1)>a1+2?a1-1:a/a1



    return ((i=(a(2)<i?i-1:a(1)>i+3?a(2)-a(1)-1:a/1)) + " line(s) "   ) + (i<a(2)?" after":(i>=a(2)?" before":"confusing")) + " me";
}


console.log (whereami ()) //3 line(s)  after me

Si une ligne vide de la whereamifonction est supprimée. La sortie est NaN line(s) confusing me. (Ajouter des lignes ne le casse pas)

It actually only counts how many lines are between i and the first and last line respectively. If they fall under a given value. The reference line is set to NaN which neither satisfies NaN<callingLine nor NaN>=callingLine. I tried to hide it a bit in unreadable ternary expressions.

C5H8NNaO4
la source
1
Cool. I hadn't thought of using the exceptions stack like that.
nderscore
2

Perl

#!/usr/bin/perl

use strict;
use warnings;

open IN, "<".$0 or die "Did not find input files!";
while (<IN>) {
        m/blabla/ && ((<IN> =~ /\}/ && print "tra-la-la...\n") || print "ti-ri-li\n");

}
close IN;

This perl script will read the script file and check if after the line containing "blabla" there is a closing bracket.

urzeit
la source
2

Escript

Due to bug in escript implementation valid escript has to be at least three lines long and first line hast to be shebang line or empty line. So following script hast to have two empty lines where first one has to be first one:

main(_) -> io:format("Hello world!~n", []), halt().

Or it hast to be broken in two lines but still has to have first empty line.

main(_) ->
    io:format("Hello world!~n", []), halt().

Otherwise you will get

escript: Premature end of file reached
Hynek -Pichi- Vychodil
la source
2

Ruby

print %q
2+2=

p(2+2)

Prints 2+2=4, but gives a syntax error without the blank third line. %q allows any non-word character to serve as a string delimiter, even the newline character. So the first three lines of code are actually equivalent to print %q"2+2=", or just print "2+2=". Since the newline after 2+2= is being used as a quote delimiter, it's not also parsed as a line delimiter, so you need another one immediately after.

histocrat
la source
1

Insomnia (both versions)!

Þyoo

â

This code prints a ~ (don't ask why, insomnia is weird). If you remove the blank line, it prints a ÿ instead.

By the way that first letter is a thorn.

pppery
la source
1
Hooray, thorns! Haven't seen that character in ages, +1.
Addison Crump
0

C++

This is a classic and rather dumb trick. You will know what it is when you see it, this is just here for completion's sake. As such, I'm marking this as a community wiki answer.

int main() {
    //This program won't work without the next line, why??/

    return 1;
}

Why this works

CrazyM4n
la source
13
This is actually one of the loopholes.
Mhmd
@Mhmd I wasn't aware. Either way, I know people always use this in these kinds of question, and I just wanted to leave this here just so someone doesn't find it clever to do this.
Aearnus
1
This answer is wrong for two reasons. The first is that ??/ means \​, so ??// means \/, and as the line doesn't end in \​, there is no line continuation. The second is that the behaviour is exactly the same regardless of whether return 0; is executed, because that is the standard behaviour when the execution of main reaches the closing }.
hvd
@hvd There. I fixed it.
Aearnus
3
@cra I know people always use this in these kinds of question that's why we made it a standard loophole
undergroundmonorail
0

Paste this into a html file, and open it in your browser. It's pretty simple, but a little tricky because it takes the number of blank lines in the document and indexes an array to call a function which shows an alert.

<body>
<script>
[null, function(){alert("GIVE ME MY LINE BACK")}, function(){alert("2 + 2 = " + (2+2))}][document.body.innerHTML.split("\n\n").length]()

</script>
</body>

This one is borderline rule breaking. Technically JavaScript doesn't have multiline strings, which is the only reason this works.

Because you can have a syntax error in one script tag without interfering with the other script tags this shows a positive result only if there's an error on the page. The error prevents the second alert from firing because it's in the same script tag.

<body>
<script>
window.onerror=function(){
  alert("2 + 2 = " + (2+2));
}
</script>
<script>
var a = "\

";
alert("GIVE ME MY LINE BACK!");
</script>
</body>
Brigand
la source
0

Ruby

puts (% #{ARGV[0].to_i + ARGV[1].to_i}

)

The secret is that the newline, is really a tab, then a new line. I don't know if this counts but I thought it was cleaver. The character after the % is also a tab, but for some reason it doesn't show up like one. I'm using Ruby's percent notation to make a string, that adds the first 2 arguments passed to the script. There's more on that here: http://teohm.com/blog/2012/10/15/start-using-ruby-percent-notation/

addison
la source
It actually doesn't count, read the instructions: "No whitespace foolery." Exactly one \n should be present and should be crucial to having the program work as expected.
Naftuli Kay
Ah ok :( well I tried
addison
1
I think you can fix this, though: a newline can itself be a percent delimiter.
histocrat