Usunięcie pustego wiersza w kodzie źródłowym, co powoduje nieoczekiwaną funkcjonalność [zamknięte]


38

Napisz skrypt, który działa dobrze, gdy w przepływie logiki programu występuje pusty wiersz, ale przerywa lub powoduje nieoczekiwane zachowanie po usunięciu tego wiersza.

Unikaj standardowych luk i głupich odpowiedzi. Twój program powinien zrobić coś „przydatnego”, nawet jeśli wystarczy dodać kilka liczb całkowitych.

Usunięcie pustej linii z ciągu wielowierszowego nie ma znaczenia, chyba że oczekiwane wyjście z tego ciągu wielowierszowego nie powinno się technicznie zmienić (tj .: jeśli usuniesz wszystkie pasujące puste wiersze ^$).

Głupstwo w białych znakach również nie jest dozwolone; nie rób dziwnych rzeczy ze zwrotami karetki, tabulatorami, spacjami itp.


11
Myślę, że powinieneś wykluczyć białe znaki.
nneonneo

17
Myślę, że Whitespace tostandardowa luka
core1024

5
nneonneo mówi o Whitespace , który jest językiem, który używa tylko spacji jako składni.
Kyle Kanos

4
„nieoczekiwana funkcjonalność” to bardzo dobre zdanie.
Kaz

3
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ słabe wyzwania nie są już na ten temat na tej stronie. meta.codegolf.stackexchange.com/a/8326/20469
kot

Odpowiedzi:


62

JavaScript

Otwiera wyskakujące okienko z komunikatem „Witaj, świecie!” jeśli pusta linia istnieje, w przeciwnym razie ostrzega „0”.

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

})();

Próbny

Wyjaśnienie:

arguments.callee jest odniesieniem do samoczynnie wykonującej się funkcji anonimowej.

Dołączenie pustej tablicy ( []) powoduje rzutowanie funkcji na ciąg znaków, co daje kod źródłowy.

indexOfzwraca, -1jeśli ciąg nie zostanie znaleziony.

Wykonywanie bitowej operacji nie ( ~) powoduje -1przekształcenie w 0wartość falsey.


2
Co to za podstęp ?!
Kroltan

1
arguments.calleezawiera źródło funkcji.
Matthew

2
Zauważ, że nie działa to już w trybie ścisłym (którego używałby najnowszy kod). Tryb ścisły zabrania używania arguments.callee.
Daniel Lo Nigro

1
@Michael: Nie, spec nie mówi nic o dokładnym formacie. W rzeczywistości istnieją silniki, które nie zachowują białych znaków.
Bergi,

2
@DanielLoNigro Możesz po prostu nadać wyrażeniu funkcji nazwę i użyć go zamiast arguments.callee. Nawet sprawia, że ​​jest krótszy.
kot

42

do

Ten magiczny program z 8 kulkami będzie nadal działał bez pustej linii, ale będzie nieco bardziej decydujący - żadna z neutralnych odpowiedzi nigdy nie pojawi się na wyjściu.

#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;
}

Wyjaśnienie

Gdy parser C widzi odwrotny ukośnik, a po nim znak nowej linii, ignoruje oba i traktuje drugą linię jako kontynuację pierwszej. Bez pustej linii wszystkie „obojętne” odpowiedzi będą traktowane jako część poprzedniego komentarza.


51
Dałem +1, ale widok komentarzy C kończących się odwrotnym ukośnikiem zaczyna stać się standardową luką, IMO.
Tim S.

2
Było to odniesienie do tego „standardowego luki” , więc może nie dosłownie „luka”.
Tim S.

5
@TimS. jeśli znudziło Cię to „rozwiązanie”, dlaczego głosowałeś?
John Dvorak

8
Odpowiedzi z odwrotnym ukośnikiem w następnej linii w komentarz (trigraf lub brak trigrafii) sprawiają, że żałuję, że nie mam 125 reputacji. I zachować widząc ich , a oni zaczynają być strasznie monotonne, całkowicie przezroczyste, a nie sprytny lub zabawne. (Co jest niefortunne dla tych, którzy ich używają, na przykład piskliwych tutaj, ponieważ w żaden sposób nie zasługują na gniew i czasami są całkowicie nieświadomi tego - ale sztuczka jest zarabianie.)
doppelgreener

4
@Jan zaczyna być standardem, nie jest tym samym, co zbyt długi / przesadzony ... jego użycie jest tutaj dość sprytne, nie wygląda nie na miejscu (w przeciwieństwie do niektórych, które widziałem, które w niewytłumaczalny sposób mają charakter koniec komentarza lub zakończ komentarze komentarzem (-ami), aby zrobić coś niezwykłego. Więc: głosuję za rozwiązaniem, a nie za dalszym wykorzystywaniem jego sztuczki.
Tim S.

37

Befunge-93

v
&
&
+
#

.
@

Mój pierwszy program befunge :)

Odczytuje dwie liczby z wejścia i wypisuje ich sumę. Jeśli usuniesz pusty wiersz, nic nie drukuje.

Wyjaśnienie:

vustawia kierunek wykonywania kodu w dół
&czyta liczbę całkowitą
+dodaje liczby razem
#pomija kolejne polecenie
.wypisuje liczbę całkowitą ze stosu
@kończy program

Jak napisano, #przeskakuje pustą linię i kontynuuje .. Kup po usunięciu pustej linii .jest pomijany.

Wydaje się, że jest miły tłumacz na http://befunge.aurlien.net/


Ach, sprytny.
patrz

1
Befunge 98 również to robi. Dobre myślenie. A ten tłumacz ma pewne zalety (nie korzystałem z twojego dużo, więc nie znam jego zalet).
Justin

32

Ruby / Shell

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

p 1+1

Działa dobrze, jeśli nowa linia znajduje się na górze, w przeciwnym razie pierwsza linia komentarza jest interpretowana przez powłokę jako zniekształcony shebang.


3
Czy to nie zawsze zadziała, czy nie zadziała? Na przykład, jeśli uruchomiłeś go jako ruby youranswer.rb, nie szukałby shebang, ponieważ jest już uruchomiony w tłumaczu ruby, ale jeśli uruchomiłeś go tak, ./youranswer.rbjakby w ogóle nie działał, ponieważ nie ma shebang ..
Przywróć Monikę

6
Przynajmniej z moim rubinem shebang jest honorowany, nawet jeśli go uruchomisz ruby youranswer.rb, co może być przydatne do ustawienia niezbędnych przełączników wiersza poleceń w pliku. Więc bez nowej linii dostajęruby: 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")
}

Jeśli usuniesz pusty wiersz, wydruk nie zostanie wydrukowany. Co jest najlepsze, ponieważ Twój stos przepełniłby się, gdybyś faktycznie sprawdził IntWrapper.

Jest to przypadek narożny wnioskowania Scala o średniku. Zwykle znaki nowego wiersza otrzymują średnik, ilekroć wynikowy kod byłby prawidłowy. Jednak twórcy Scali nie chcieli zmusić ludzi do używania nawiasów egipskich , więc poprawne jest umieszczenie nawiasów dla definicji klasy w wierszu natychmiast po nim - nie dodaje się średnika, nawet jeśli można. Jednak pusta linia oddziela nawiasy kwadratowe od definicji klasy. Po usunięciu pustego wiersza kod zmienia się z definicji klasy i bloku w definicję klasy z konstruktorem - i konstruktorem rekurencyjnym!


6
Bardzo miło, że nie zmuszają egipskich wsporników. Jednak moim zdaniem, wnioskowanie o średnikach jest złym pomysłem.
Almo

Wnioskowanie o średniku dostaje złą nazwę, głównie z powodu JavaScript. To trochę mniej bolesne, jeśli projektujesz język z myślą o nim (na przykład nikt nie narzeka na to w Pythonie). Niestety Scala zawiera kilka funkcji, które nie działają dobrze z wnioskowaniem średnika. Jest to i operatorzy Postfiksów (których chciałem użyć w swojej odpowiedzi, ale to trochę passé).
James_pic

2
@James_pic: AFAIK nikt nie narzeka w Pythonie, ponieważ nie istnieje w Pythonie. W JS średniki są niezbędną częścią składni i mogą być wstawiane (wywnioskowane) w niektórych punktach. W Pythonie średniki nie są niezbędną częścią składni, ale mogą być używane opcjonalnie. To duża różnica.
Mason Wheeler

Może się to wydawać dużą różnicą, ale gdyby Scala usunął kilka funkcji, które obecnie sprawiają, że granice instrukcji są niejednoznaczne, przenosiłby się ze strony ogrodzenia JavaScript do strony Pythona.
James_pic

1
@James_pic: Co odróżnia Pythona, to to, że znak nowej linii kończy instrukcję, chyba że jest poprzedzony znakiem ucieczki lub wewnątrz nawiasów. Oznacza to, że nie ma pełnej / niepełnej reguły.
Jan Hudec

27

GolfScript

~{.@\%:

}do;

Oblicza GCD dwóch niezerowych liczb całkowitych. Usunięcie pustej linii powoduje uszkodzenie programu.

Wypróbuj online.

Jak to działa

To jest implementacja algorytmu euklidesowego w języku GolfScript:

      # 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.

Jest tylko jeden mały problem:

{}dowyskakuje moduł ze stosu, aby sprawdzić, czy jest on prawdziwy, więc musi zostać zduplikowany na końcu pętli. Zwykle osiąga się to przez ., ale :\n\nma ten sam efekt: przechowuje najwyższy element stosu w zmiennej LF ( :\n), a następnie wypycha zawartość tej zmiennej.


7
Wow, nawet to zmienna? : O
aditsu

@aditsu: Tylko #, {i }nie mogą być używane jako nazwy zmiennych, ponieważ są one częścią składni. Każdy inny token jest w porządku, w tym łańcuchy.
Dennis

@Dennis wow. Nawet zmienne TIL mogą być używane jako zmienne. Czy to się przydaje?
John Dvorak,

@JanDvorak: Poza niektórymi przypadkami na krawędziach (kod palindromiczny, podstępny kod , prawdopodobnie nie. Myślę, że to tylko ( udokumentowany ) efekt uboczny tego, jak interpreter GolfScript dzieli kod na tokeny.
Dennis,

@Dennis czy to oznacza, że .:-1przechowuje dane wejściowe -1, a nie sam znak minus? Hmm ...
John Dvorak,

23

Składnia szablonu MediaWiki

Zdefiniuj szablon: Foo as

{{{a

b|Uh-oh!}}}

Na innej stronie

{{Foo|a

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

{{Foo|a


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

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

W MediaWiki nazwy parametrów mogą zawierać znaki nowej linii.


1
Fajnie, to jest zgodne z tym, czego szukałem, takie dziwne przypadki na krawędzi.
Naftuli Kay

16

LaTeX (backref)

Poniższy kod LaTeX używa cytatu, który zawiera listę stron, na których cytowany jest wpis. Oto pierwsza strona. Pakiet hyperrefdodaje również linki PDF, odnośnik do strony jest czerwony, link cytatu jest zielony.

\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}

Wynik

Ale LaTeX nie wymaga pustej linii, pusta linia wygląda na zbędną, a przykład nadal będzie działał bez, hyperrefa pusta linia:

\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}

Wynik bez hiperref

Ale linki i referencje zniknęły, dlatego ponownie je wstawiamy:

\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}

Ale teraz przykład jest zepsuty i nie będzie się już kompilował :

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

?

Co się stało? Pakiet hyperref(lub bardziej precyzyjny pakiet backref, który jest ładowany hyperref) chce uzyskać na końcu pozycji bibliografii, aby dodać tylną listę referencyjną. Ale składnia w LaTeX zapewnia tylko początek wpisu \bibitem, koniec może być wszędzie. W tym pakiecie awaryjnym backrefdodano ograniczenie, które \bibitemmusi kończyć wpis pustą linią. Następnie pakiet może przedefiniować, \bibitemaby umieścić referencje na końcu wpisu.

Ponieważ brakuje pustej linii, TeX wciąż go szuka, ale zamiast tego znalazł koniec pliku i wyświetla komunikat o błędzie.


12

C (częściowo zaciemniony)

Ten mały program pobiera liczbę z wiersza poleceń i oblicza silnię. Zawiera jednak także najnowocześniejsze funkcje AI do weryfikacji środowiska wykonawczego, czy przestrzegane są standardy kodowania firmy, w tym prawidłowe użycie białych znaków i pustych linii. Usunięcie pustej linii spowoduje, że algorytm odrzuci program, który nie nadaje się do utrzymania w wystarczającym stopniu.

Nigdzie nie ma żadnych kontynuacji linii ani kaligrafii. Uważam, że jest to poprawne ANSI C99.

Ze względu na zaawansowaną matematykę, jeśli się kompilujesz gcc, pamiętaj o użyciu -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;
}

Spojler

Skomplikowana vrfyfunkcja nigdy nie jest wywoływana, a raczej zabawnie wyglądające vfrymakro. Użycie funkcji konkatenacji łańcuchów preprocesora ukrywa fakt, że tak naprawdę sprawdzamy tylko parzystość __LINE__.


Współpracuje również ztcc -run
Vi.

To jest naprawdę fajne. To vfrynie jest rozwinięte w definicji funkcji, naprawdę mnie zaskoczyło.
FUZxxl,

11

do

Ten program działa zgodnie z oczekiwaniami (jak opisano w komentarzach), chyba że poprzednia pusta linia foo = 5;zostanie usunięta.

Niestety raz napotkałem błąd prawie dokładnie taki jak ten w kodzie produkcyjnym.

#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;
}

W tym przykładzie użyto do { ... } while (0)idiomu do utworzenia instrukcji wielowierszowej w makrze (patrz https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for ). Używa także znaku odwrotnego ukośnika, aby rozłożyć #definewiele linii, wygodnie ustawionych w linii poza zasięgiem wzroku. Jednak robi to również dwie rzeczy źle:

  • Po niej pojawia się średnik while (0), a idiom zwykle tego pomija
  • Po ostatniej linii znaku jest odwrotny #define

Mając to na miejscu, usuwając pusty wiersz przed foo = 5;przyczyn, które zadanie do wykonania poprintf , ale także po każdym wezwaniem FROBmakro. W rezultacie wynik po usunięciu pustego wiersza to:

1
6
6


@ TheRare Ale to mniej oczywiste.
Ypnypn

6
Jest to mniej oczywiste, jeśli nie spojrzysz na te ukośniki unoszące się bardzo wyraźnie w prawo. (Ale ponieważ pływają tam bardzo wyraźnie po prawej stronie, zostaną
popatrzone

3
Jednak wszystkie oprócz jednego są uzasadnione
QuadmasterXLII

6
@QuadmasterXLII, technicznie rzecz biorąc, wszystkie są uzasadnione - dokładnie uzasadnione, a konkretnie.
Mark

9

C / C ++

int main(){

    return __LINE__ - 3;
}

Zwraca sukces i może być wykorzystany jako implementacja true . Jeśli pusty wiersz zostanie usunięty, możesz zamiast tego użyć go jako implementacji wartości false .


8

PowerShell

Ta funkcja doda dwie liczby.

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

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

Usunięcie pustej linii spowoduje awarię funkcji przy: Unexpected token '$b' in expression or statement.

Wyjaśnienie

Elementy tablicy można oddzielić znakami nowej linii i / lub przecinkami. Umieszczenie znaku kontynuacji linii ( `) po $awymaga dodatkowej nowej linii do oddzielenia $ai $b. W przeciwnym razie interpreter wyświetli kod jako $numbers = @($a $b)(bez separatora elementów).


7

TeX

\noindent\everypar{$\bullet$ hello }

world
\bye

Bez pustej linii „cześć” nie jest drukowane.

Wyjaśnienie

TeX traktuje pustą linię jako podział akapitu i \everyparjest wykonywany na początku nowego akapitu.


6

Jawa

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 jest bieżącym numerem linii, y jest bieżącym numerem linii - x. Jeśli między nimi jest pusta linia, wynikiem jest 2. Zatem kod oblicza liczbę 2 ^.


1
+1 po prostu dlatego, że jest to Java, chociaż jako częsty gość Code Review zastanawiam się, dlaczego nie używasz Math.pow?
Simon Forsberg,

Ponieważ mój kod musi coś zrobić. Dodanie 2 liczb jest trochę zbyt proste.
barteks2x

Używanie Math.powi wydrukowanie wyników oznacza robienie czegoś , prawda?
Simon Forsberg,

A teraz zdałem sobie sprawę, że naprawdę mogę użyć .Math.pow Nie wiem, dlaczego myślałem, że muszę to zrobić w ten sposób ... Matbe Chciałem to zrobić w bardziej „podstępny” sposób.
barteks2x

7
Za dużo grałeś w golfa. Zamiast tego powinieneś odwiedzić Code Review, gdzie robimy wszystko dobrze!
Simon Forsberg,

6

Perl 5

print(<<""
Hello, World!

);

Ten kod jest drukowany Hello, World!. Usunięcie pustej linii powoduje błąd składniowy.

Wyjaśnienie:

Składnia tutaj-doc Perla dla ciągów wieloliniowych pozwala na pusty ciąg terminatora. Jest to nawet wyraźnie udokumentowane. Usunięcie pustej linii powoduje, że nawias zamykający (i wszystko do następnego pustego wiersza, jeśli taki istnieje) jest interpretowany jako część ciągu, co powoduje błąd składniowy.

Wyświetlane komunikaty o błędach są całkiem przyzwoite, jak na taką dziwną funkcję składni. Jeśli w programie po print(<<""wierszu nie ma żadnych pustych wierszy , Perl po prostu mówi:

Nie mogę znaleźć terminatora „” gdziekolwiek przed EOF w linii 1 foo.pl.

Jeśli na końcu programu jest pusta linia, zamiast tego pojawi się coś takiego:

błąd składni w linii 4 foo.pl, w EOF
  (Może być niekontrolowanym ciągiem << wielu linii zaczynającym się od linii 1)
Wykonanie foo.pl przerwane z powodu błędów kompilacji.


5

Partia

@echo off
setLocal enableDelayedExpansion
set NL=^


echo Hello!NL!World

Ten kod wyświetli Helloi w następnym wierszu World. Po usunięciu jednego lub obu pustych wierszy nic nie wyświetla.

Tutaj jest wyjaśnienie .


4

Rubin

Usunięcie pierwszego wiersza spowoduje błąd:

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

2
Podoba mi się komunikat o błędzie. Chciałbym zobaczyć reakcję osoby, która próbuje uruchomić program i otrzymuje tę odpowiedź.
tomsmeding

4

Pyton

Nie wiem, czy to mieści się w standardowych lukach, spojrzałem na listę i tego nie widziałem.

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

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

Uruchomienie tego regularnie powraca

Hello World!

Uruchamianie go bez pustej linii w linii 4, tj. Jak poniżej:

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

nic nie zwraca.


3

Python 2.x

Ten program wypisuje piąty znak wprowadzonego ciągu.

import inspect

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

To nie jest w żaden sposób ukryte. Jeśli usuniesz pustą linię, daje ona czwarty znak, a szósty, jeśli dodasz jeden.


3

Tcl

Funkcja, która dodaje dwie liczby (i sprawdza, czy nowa linia została usunięta):

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

    return [expr $a+$b]
}

Nie ma tu nic do ukrycia, robi to, co mówi, więc nie psuję wyjaśnienia. Ta funkcja infoto szwajcarski scyzoryk introspekcji (co inne języki nazywają odbiciem). info bodyzwraca kod źródłowy funkcji (jeśli nie jest napisany w C lub asemblerze).

Muszę przyznać, że to mnie zaskoczyło, dopóki nie zobaczyłem rozwiązania javascript.


3

do

#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;
}

W pustym wierszu ajest zmienną lokalną a, a bez parametru makra ...


3

Technicznie nie jest to problem z „kodem”, ale problem z serwerem. Jeśli zostanie to wysłane do Apache ze skryptu CGI (który można wygenerować w dowolnym języku), wyśle ​​odpowiedź HTTP do klienta:

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

Hello world!

Z drugiej strony to się nie powiedzie, ponieważ brakuje pustego miejsca po nagłówku.

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

2

JavaScript

Funkcja whereamiodpowiada pozycją linii wywołującej względem jej własnej pozycji w kodzie źródłowym.

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

Jeśli jakaś pusta linia w whereamifunkcji zostanie usunięta. Dane wyjściowe to NaN line(s) confusing me. (Dodanie linii nie łamie go)

W rzeczywistości liczy się tylko, ile linii znajduje się odpowiednio między ipierwszą i ostatnią linią. Jeśli mieszczą się poniżej określonej wartości. Ustawiona jest linia odniesienia, NaNktóra nie spełnia NaN<callingLineani NaN>=callingLine. Próbowałem to trochę ukryć w nieczytelnych potrójnych wyrażeniach.


1
Fajne. Nie myślałem o takim stosie wyjątków.
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;

Ten skrypt w Perlu odczyta plik skryptu i sprawdzi, czy po wierszu zawierającym „blabla” znajduje się nawias zamykający.


2

Escript

Z powodu błędu w escriptimplementacji poprawny skrypt musi mieć co najmniej trzy linie długości, a pierwsza linia musi być linią shebang lub linią pustą. Zatem poniższy skrypt musi mieć dwie puste linie, w których pierwszy musi być pierwszy:

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

Lub musi być podzielony na dwie linie, ale wciąż musi mieć pierwszą pustą linię.

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

W przeciwnym razie dostaniesz

escript: Premature end of file reached

2

Rubin

print %q
2+2=

p(2+2)

Drukuje 2+2=4, ale podaje błąd składniowy bez pustej trzeciej linii. %qpozwala dowolnemu znakowi niebędącemu słowem służyć jako ogranicznik łańcucha, nawet znakowi nowej linii. Tak więc pierwsze trzy wiersze kodu są w rzeczywistości równoważne print %q"2+2="lub po prostu print "2+2=". Ponieważ nowa linia po 2+2=jest używana jako ogranicznik cudzysłowu, nie jest również analizowana jako ogranicznik wiersza , więc potrzebujesz następnej zaraz po niej.


1

Bezsenność (obie wersje)!

Þyoo

â

Ten kod wypisuje ~ (nie pytaj dlaczego, bezsenność jest dziwna). Jeśli usuniesz pustą linię, zamiast niej zostanie wydrukowane ÿ.

Nawiasem mówiąc, ta pierwsza litera jest kolcem .


1
Brawo, kolce! Nie widziałem tej postaci od wieków, +1.
Addison Crump

0

C ++

To klasyczna i raczej głupia sztuczka. Będziesz wiedział, co to jest, kiedy to zobaczysz, to tylko tutaj, ze względu na zakończenie. Jako taki, zaznaczam to jako odpowiedź wiki społeczności.

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

    return 1;
}

Dlaczego to działa


13
To właściwie jedna z luk.
Mhmd

@Mhmd Nie byłem świadomy. Tak czy inaczej, wiem, że ludzie zawsze używają tego w tego rodzaju pytaniach, a ja po prostu chciałem zostawić to tutaj, aby ktoś nie uważał tego za mądre.
Aearnus

1
Ta odpowiedź jest błędna z dwóch powodów. Po pierwsze, ??/oznacza to , a \​więc ??//oznacza \/, a ponieważ linia się nie kończy \​, nie ma kontynuacji linii. Po drugie, zachowanie jest dokładnie takie samo bez względu na return 0;to, czy jest wykonywane, ponieważ jest to standardowe zachowanie, gdy wykonanie mainzamyka się }.
hvd

@hvd There. Naprawiłem to.
Aearnus

3
@cra I know people always use this in these kinds of questiondlatego stworzyliśmy standardową lukę
undergroundmonorail

0

Wklej to do pliku HTML i otwórz w przeglądarce. Jest to dość proste, ale trochę trudne, ponieważ wymaga liczby pustych wierszy w dokumencie i indeksuje tablicę w celu wywołania funkcji, która wyświetla 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>

Ten łamie zasady graniczne. Technicznie JavaScript nie ma ciągów wielowierszowych, co jest jedynym powodem, dla którego to działa.

Ponieważ możesz mieć błąd składniowy w jednym znaczniku skryptu bez ingerencji w inne znaczniki skryptu, pokazuje to pozytywny wynik tylko wtedy, gdy na stronie wystąpi błąd. Błąd uniemożliwia uruchomienie drugiego alertu, ponieważ znajduje się w tym samym znaczniku skryptu.

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

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

0

Rubin

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

)

Sekret polega na tym, że nowa linia to tak naprawdę karta, a następnie nowa linia. Nie wiem, czy to się liczy, ale myślałem, że to tasak. Znak po znaku %jest również tabulatorem, ale z jakiegoś powodu nie pokazuje się jak jeden. Używam notacji procentowej Ruby, aby utworzyć ciąg, który dodaje pierwsze 2 argumenty przekazane do skryptu. Więcej na ten temat tutaj: http://teohm.com/blog/2012/10/15/start-using-ruby-percent-notation/


W rzeczywistości to się nie liczy, przeczytaj instrukcję: „Żadnych głupców z białych znaków”. Dokładnie \ntrzeba być obecnym i mieć kluczowe znaczenie dla prawidłowego działania programu.
Naftuli Kay

Ach ok :( dobrze próbowałem
addison

1
Myślę jednak, że możesz to naprawić: nowa linia może sama być separatorem procentowym.
histocrat
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.