Quelle est, à votre avis, la fonctionnalité de langage la plus surprenante, étrange, étrange ou vraiment "WTF" que vous avez rencontrée?
S'il vous plaît, une seule caractéristique par réponse.
Tongs Ruby. "..." et ".." dans les instructions conditionnelles ne sont pas toujours des opérateurs de plage:
(0..20).each do |x|
if ((x%10) == 5)..((x%10) == 5)
print "#{x} "
end
end
(0..20).each do |x|
if ((x%10) == 5)...((x%10) == 5)
print "#{x} "
end
end
Cela produira:
5 15
5 6 7 8 9 10 11 12 13 14 15
.. vérifie les deux instructions à chaque passe, ... ne vérifie que les instructions "on" ou "off" à chaque passe (en fonction de l'état de la bascule). Ils sont volés à awk et sed.
Matz écrit dans "Le Ruby Langage de programmation" ":" Les bascules sont une fonctionnalité assez obscure de Ruby et devraient probablement être évitées ... "
var_export('false' == 0); // true
var_export('false' == true); // true
var_export('false' == false); // false
EDIT
Comme @Kobi l'a mentionné, cela peut arriver parce que le langage interprète toute valeur comme "TRUE" sauf "FALSE", mais pas dans le cas de PHP, où les choses sont encore plus étranges que vous ne le pensiez!
Ce cas est entièrement documenté dans le chapitre "Conversion de chaînes en nombres" d'un manuel PHP, qui dit:
Si la chaîne commence par des données numériques valides, il s'agira de la valeur utilisée. Sinon, la valeur sera 0 (zéro).
Voici un exemple:
print (int) 'zero'; // 0
print (int) 'false'; // 0
// but
print (int) '1 - one'; // 1
P.S. Je vois plus de mal que d’utilité de telles conversions de types implicites.
Depuis que je n'ai vu personne le mentionner ... RPG 2 ou 3 (Générateur de programme de rapport ... ou Rocket Propelled Garbage) est de loin le langage le plus crasseux que j'ai jamais utilisé. Il combine pratiquement aucun contrôle sur le flux du programme (Entrée en haut du fichier, Sortie en bas) et les instructions de programmation sont définies en fonction des caractères définis dans des colonnes spécifiques en utilisant une police fixe (pensez PUNCH CARDS !!).
Pour être vraiment FUBAR, vous devez essayer de programmer en DYL-280. Il combinait flux et logique RPG avec la syntaxe COBOL.
Regardez ici pour RPG: wikipedia.org/wiki/IBM_RPG
Un exemple de DYL-280: http://99-bottles-of-beer.net/language-dyl-280-224.html
Pour ceux qui ne le savaient pas, PostScript est en réalité un langage de programmation. Je suis devenu un peu fou avec cela - j'ai écrit un programme PostScript qui calcule une fractale de Mandelbrot avec un niveau de détail très élevé. C'est vraiment du PostScript imprimable, même s'il va planter beaucoup de pilotes d'impression ...
Quoi qu'il en soit, par où commencer avec PostScript ... En voici une: vous pouvez créer une variable dont l'identifiant est .... rien.
() cvn 5 def% Attribuez le nombre 5 à ... rien
PostScript est un langage basé sur la pile. () place une chaîne vide sur la pile. cvn le convertit en un nom ("/" si vous l'imprimez, car tous les noms dans PS sont précédés d'une barre oblique). Ensuite, 5 def lui attribue la valeur 5. (% est le caractère de commentaire)
Vous ne pouvez pas le récupérer directement, par exemple si je dis "/ print", cela n'imprimera pas le chiffre 5. Mais vous pouvez le récupérer indirectement:
() cvn load print% this affichera le nombre 5
Quoi d'autre ... PostScript a des dictionnaires en tant que type natif, et vous pouvez utiliser une référence de tableau comme clé du dictionnaire ... mais c'est le REFERENCE qui est la clé, pas le tableau. Alors:
/ myDict 100 dict def
[0] dup myDict exch 42 mis myDict exch get ==% empreintes 42
myDict [1] 42 put myDict [1] get% lève une erreur non définie
Edit: Oh oui, encore une chose amusante ... Essayez ce qui suit à l'invite de Ghostscript:
1 array dup dup 0 exch put ==
D'oh!
En Ruby, vous pouvez faire des choses bizarres avec heredocs. Considérer:
a = <<ONE
This is one. #{<<TWO}
This is two. #{<<THREE}
This is three.
THREE
TWO
ONE
p a # => "This is one. This is two. This is three.\n\n\n"
Un de mes favoris C++:
#include <iostream>
using namespace std;
int main()
{
cout << 3 << 5 << endl;
cout << (3 << 5) << endl;
return 0;
}
Bien sûr, cela s’explique facilement, mais cela a déjà commencé à programmer les étudiants à se gratter la tête!
Le langage de programmation RSL est utilisé dans un système bancaire étrange. Il existe une classe intégrée TArray
pour les tableaux. Mais si vous en héritez, chaque variable d'instance devient un élément du tableau.
class (TArray) DerivedArray
var someField = 56;
end
var a = DerivedArray();
PrintLn(a.Size); // => 1
PrintLn(a[0]); // => 56
PHP backticks
De http://www.php.net/manual/en/language.operators.execution.php
PHP supporte un opérateur d'exécution: backticks (``). Notez que ce ne sont pas des guillemets simples! PHP tentera d'exécuter le contenu des backticks en tant que commande Shell. la sortie sera renvoyée (c’est-à-dire qu’elle ne sera pas simplement exportée dans la sortie; elle peut être affectée à une variable).
$output = `ls -al`;
echo "<pre>$output</pre>";
Eh bien, il est "assez facile" de trouver "au lieu de" dans le code.
C'est drôle aussi:
Après beaucoup de problèmes, j'ai conclu que l'opérateur de backtick (et Shell_exec) ont un tampon limité pour le retour. Mon problème était que je cherchais un fichier avec plus de 500 000 lignes, recevant une réponse avec plus de 100 000 lignes. Après une courte pause, grep m'a submergé d'erreurs concernant la fermeture du tuyau.
Voici quelques exemples du débogueur Perl:
DB<1> sub foo { +(1..20) }
DB<2> @bar = foo(); # list of 1, 2, 3, 4...20
DB<3> x scalar @bar # size of list
0 20
DB<4> x scalar foo();
0 ''
C'est vrai. Lorsque vous appelez la méthode de cette manière, le contexte scalaire de scalar
se propage dans l'appel du sous-programme, transformant ainsi le ..
inoffensif en un opérateur totalement différent. (C'est l'opérateur "bascule", au lieu de l'opérateur de plage).
Feature: Bash, le shell Korn (ksh93) et le shell Z permettent chacun des tableaux en indice avec des variables avec ou sans signe dollar:
array[index]=$value
array[$index]=$value
Ceci, avec le signe dollar, produira la valeur attendue de 10000:
unset array
for i in {1..10000}
do
((array[$RANDOM%6+1]++))
done
unset total
for count in ${array[@]}
do
((total += count))
done
echo $total
Étrangeté: Si vous supprimez le signe dollar de RANDOM, le total variera de manière aléatoire, pouvant même dépasser 10000.
De même, cela produit 3 au lieu de 2:
a=1; ((r[a++]++)); echo $a
Et vous ne pouvez pas utiliser un signe dollar ici car il s'agit d'une affectation (a est sur le lhs), bien que vous puissiez le faire si vous utilisiez l'indirection, mais la double évaluation se produit toujours.
The Reason: Avec le signe dollar, l’extension variable est effectuée avant l’évaluation arithmétique et n’est donc effectuée qu’une fois. Sans le signe dollar, elle est exécutée deux fois, une fois pour calculer l’indice de recherche et une autre fois pour calculer l’indice de l’affectation (de sorte qu’une affectation à une étape de la boucle peut ressembler à array[4] = $array[6] + 1
qui brouille le tableau).
Qu'en est-il des trop-pleins dépendant du système qui entraînent des changements d'année dans (MRI/C) Ruby et MacRuby (mais pas dans JRuby), suivis par des erreurs d'heure locale pour un plus grand nombre. Pas un problème commun, mais c'est étrange:
$ Ruby -version
Ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
$ irb
>> Time.at(67767976233550799)
=> Tue Dec 31 23:59:59 -0500 2147483647
>> Time.at(67767976233550800)
=> Wed Jan 01 00:00:00 -0500 -2147483648
>> Time.at(67768036191694799)
=> Wed Dec 31 23:59:59 -0500 -2147481749
>> Time.at(67768036191694800)
ArgumentError: localtime error
...
Maybe IRB bug!!
Cela peut être spécifique aux environnements 64 bits, cependant.
Quelque chose de bizarre - VBScript ayant à la fois un mot clé Null
et un mot clé Nothing
(Null
manque de données et Nothing
est un objet manquant). Pourquoi ne pas avoir un mot clé ...? La plupart des autres langues semblent bien fonctionner avec une seule!
Visual Basic 6.0 et bien sûr le code "ASP classique" (car il utilise VBScript) ont le même bizarrity. Et dans Visual Basic, ancien et nouveau, nous avons également DBNull
.
La situation s'améliore toutefois, car dans Visual Basic.NET, Null
a finalement disparu, de sorte que Null
est inutilisé et que seuls Nothing
et DBNull
sont utilisés.
sa = "a =" "a =" "" "a" "", @ a = "" "" 2N "" "" ", a =" "" "c =" "" "_ (" "" "" 22 "" ""? @ A), @ a "", @ a, a = "" a "", a (c) = "" S + "" _ c, e = $ T (@@ a @ (c) )",@une
c'est un Nice one-liner en COS (cache objectscript). La chose amusante à noter ici sont 5 modes différents de code-indirection * G
Les autres n'ont rien de surprenant Ruby Opérateur de bascule:
p = proc {|a,b| a..b ? "yes" : "no" }
p[false,false] => "no"
p[true,false] => "yes"
p[false,false] => "yes" # ???
p[false,true] => "yes"
p[false,false] => "no"
Oui, l'état du programme stocké dans l'arbre d'analyse de l'interpréteur. Des choses comme celle-ci expliquent pourquoi il faut une éternité pour réaliser une implémentation Ruby conforme. Mais je te pardonne, Ruby <3
En PHP, les éléments suivants:
<?php $foo = 'abc'; echo "{$foo";
est une erreur de syntaxe.
Si vous vouliez réellement {
suivi du contenu de $foo
, vous devrez utiliser .
:
<?php $foo = 'abc'; echo '{' . $foo;
Processing (processing.org) est un langage basé sur Java. En termes simples, le compilateur de traitement est un préprocesseur Java qui traduit la syntaxe spécifique au traitement en Java.
En raison de la conception de la langue, il a quelques surprises:
Les classes de traitement sont compilées dans la classe interne Java, ce qui crée un désagrément, comme des variables privées qui ne sont pas vraiment privées.
class Foo {
private int var = 0; // compiles fine
}
void setup() {
Foo f = new Foo();
print(f.var); // but does not causes compile error
}
de plus, la fonction draw () manquante empêche les gestionnaires d'événements d'être appelés:
// void draw() {} // if you forgot to include this
void mousePressed() {
print("this is never called");
}
Notation polonaise inversée (RPN). Cela signifie que les arguments précèdent la fonction. Ou, en d'autres termes, vous ajoutez deux et deux en écrivant 2 2 +
.
Les langages utilisant cette WTF incluent Forth, PostScript (oui, des imprimantes laser) et Factor.
Un compilateur Fortran que j’utilisais il y a des années présentait une caractéristique intéressante: (a) les numéros étaient stockés en octets élevés en premier; (b) Les numéros ont été passés aux sous-programmes par adresse; (c) Il n'y a pas eu de vérification de longueur lors de la compilation.
Ainsi, vous pourriez écrire un programme comme celui-ci: (Excusez-moi si je dérange la syntaxe. Cela fait longtemps que je n’ai pas écrit Fortran.)
INTEGER*2 FUNCTION TIMESTWO (INTEGER*2 N)
RETURN N*2
... THEN CALL THIS SOMEWHERE WITH A LONG INTEGER ...
INTEGER*4 I, J
I=42
J=TIMESTWO(I)
La valeur finale de J est ... zéro!
Pourquoi? Parce que la valeur transmise est de 4 octets, mais que la fonction appelée ne regarde que les deux premiers octets. Comme les deux premiers sont égaux à zéro, il double le zéro et le renvoie. Cette valeur de retour est ensuite reconvertie en quatre octets.
C'était très mystérieux quand je l'ai rencontré pour la première fois. Presque tous les numéros que j'ai transmis à certaines fonctions ont été interprétés comme zéro!
Une très petite chose qui m'a agacé en COBOL est qu'il n'y avait pas d'opération modulo dédiée. Au lieu de cela, vous pouvez créer une division spécifiant que vous voulez uniquement des résultats de nombres entiers et stocker le reste dans une variable différente. Comme COBOL est très sensible aux variables, cela signifie que vous vous retrouvez avec une variable dont vous n’avez pas vraiment besoin, c’est-à-dire le résultat réel de la division. C’est l’histoire de la façon dont j’ai nommé une variable "USELESS" - c’était le nom le plus approprié auquel je pouvais penser.
La bibliothèque CORE :: open et standard de Perl ayant des éléments d'orientation d'objet masqués par une interface procédurale: open ( my $fh, '>', 'foobar' );
open est un constructeur qui agit sur la référence renvoyée par my()
, et prend les arguments '>', et 'foobar'. De plus, il s’agit d’un objet qui est un typeglob béni (c’est-à-dire qu’il ne peut pas conserver d’état dans l’objet).
Plus d'informations sur mon post perlmonks IO :: Fichier vs CORE :: ouvert ici: http://www.perlmonks.org/? node_id = 763565
Dans Bash, les variables peuvent sembler être à la fois des scalaires et des tableaux:
$ a=3
$ echo $a
3
$ echo ${a[@]} # treat it like an array
3
$ declare -p a # but it's not
declare -- a="3"
$ a[1]=4 # treat it like an array
$ echo $a # acts like it's scalar
3
$ echo ${a[@]} # but it's not
3 4
$ declare -p a
declare -a a='([0]="3" [1]="4")'
$ a=5 # treat it like a scalar
$ echo $a # acts like it's scalar
5
$ echo ${a[@]} # but it's not
5 4
$ declare -p a
declare -a a='([0]="5" [1]="4")'
ksh fait la même chose, mais utilise typeset
au lieu de declare
.
Lorsque vous faites cela dans zsh, vous obtenez une affectation de sous-chaîne au lieu de tableaux:
$ a=3
$ a[2]=4 # zsh is one-indexed by default
$ echo $a
34
$ a[3]=567
$ echo $a
34567
$ a[3]=9
$ echo $a
34967
$ a[3]=123 # here it overwrites the first character, but inserts the others
$ echo $a
3412367
$ a=(1 2 3)
$ echo $a
1 2 3 # it's an array without needing to use ${a[@]} (but it will work)
$ a[2]=99 # what about assignments?
$ echo $a
1 99 3
En serveur SQL (au moins MS):
Ceci sera toujours considéré comme faux:
IF @someint <> NULL
Donné:
DECLARE @int INT
SET @int = 6
IF @int <> NULL
BEGIN
Print '@int is not null'
END
ELSE
BEGIN
Print '@int is evaluating to null'
END
La sortie sera:
@int is evaluating to null
Il doit être écrit:
IF @someint IS NOT NULL
BEGIN
END
Qui a mis les majors anglais dans l'équipe SQL! :)
À l'Ohio State University, ils enseignent la programmation à l'aide d'un langage bâtard appelé C++ appelé Resolve/C++. Resolve/C++ utilise une méthodologie de conception par contrat pour tout. Pour cela, vous devez modéliser mathématiquement les composants et les méthodes au sein des commentaires compilés de manière à vous obliger à gérer une relation entre les méthodes et les objets.
En C++, possibilité de créer un destructeur privé virtuel pur de base virtuelle abstraite protégée.
Il s'agit d'un destructeur privé virtuel pur hérité d'une base virtuelle abstraite protégée.
IOW, un destructeur qui ne peut être appelé que par des membres ou des amis de la classe (privé), et auquel un 0 (virtuel pur) est attribué dans la classe de base (base abstraite) qui le déclare et qui sera défini ultérieurement/remplacé dans une classe dérivée qui partage la base multi-héritée (base virtuelle) de manière protégée.
dans Ruby ...
i=true
while(i)
i=false
a=2
end
puts defined?(a) // returns true
FORTRAN n’est pas vraiment un moment WTF mais c’est plutôt un "Pourquoi dois-je saisir tout ce moment si désagréable"
IF(12 .gt. 11) THEN
// Do some magic
ENDIF
Le ".gt." m'a jeté un peu pendant que je jouais un peu avec la langue jusqu'à ce que je réalise que c'était le symbole ">". Oh, comme j'aime ne pas être majeur en biologie et avoir à barboter dans cette merde au jour le jour
Dans Common LISP, les tableaux de dimensions nulles sont étranges et ont naturellement une syntaxe en lecture.
? (aref #0A5)
5
Je pense que celui-ci n'est pas réellement une "fonctionnalité linguistique" (C) et je suis peut-être très ignorant dans sa publication, mais je ne peux pas comprendre pourquoi cela se produit, alors je vais demander. S'il s'avère que cela a un rapport avec une langue étrange ... eh bien, ça m'a vraiment fait "WTF", ça vaut donc la peine.
int a = 0;
int *p = &a;
printf("%d, %d, %d.\n", *p, (*p)++, *p); // Outputs "1, 0, 0.\n" on MinGW's GCC 4.4.1
Pourquoi?
-- modifier
Je viens de l'obtenir, et ce n'est pas grave. Je peux sentir les gourous du C++ se moquer de moi maintenant. J'imagine que l'ordre dans lequel les paramètres de fonction sont évalués n'est pas spécifié. Les compilateurs sont donc libres de les appeler à leur guise (et je pense l'avoir lu quelque part dans la documentation de boost). Dans ce cas, les instructions d'argument ont été évaluées à l'envers, reflétant probablement la convention d'appel de la fonction.
Dans LISP, vous pouvez copier une liste et copier un vecteur. Vous pouvez également copier une structure et copier un objet CLOS.
... mais vous ne pouvez pas copier un tableau ou une table de hachage.
Pas techniquement un langage WTF, mais une architecture.
http://www.6502.org/tutorials/6502opcodes.html#JMP
6502 Assemblage, JMP indirect:
Notez qu'il n'y a pas de retenue associée au saut indirect donc:
UN JUMP INDIRECT NE DOIT JAMAIS UTILISER UN
VECTEUR COMMENCANT LE DERNIER BYTE
D'une page
Par exemple, si l'adresse $ 3000 contient 40 $, 30 $ F contient 80 $ et 3100 $ contient 50 $, le résultat de JMP (30 $) sera un transfert de contrôle à 4080 $ au lieu de 5080 $ comme vous le souhaitez, c’est-à-dire que le 6502 a pris l’octet de poids faible de l’adresse. à partir de 30FF $ et l'octet élevé à partir de 3000 $.
Donc, ajouter un seul octet à votre code pourrait rendre votre saut indirect complètement fou.
Perl peut convertir automatiquement la base 26 en base 10, si vous pouvez vivre avec vous-même le matin ...
$ Perl -E "say lc (@a='a'..'asdf')"
30530
Je ne peux pas croire que celui-ci ne soit pas encore disponible: accès à la propriété JSF.
Dans une balise d'interface utilisateur JSF, vous placeriez la valeur d'une propriété de l'objet côté serveur dans l'interface en la référençant ainsi:
<h:inputText value="#{myObject.property}></h:inputText>
Le problème est que Java ne prend pas en charge les propriétés. Vous devez donc écrire des méthodes commençant par get et set afin de lier l'objet d'interface utilisateur à la "propriété" du serveur.
public void setProperty(String property){...}
public String getProperty(){...}
Cela m'a dérouté lorsque j'ai appris JSF pour la première fois et que je le considère toujours comme digne de WTF ... même s'il n'y a vraiment aucun autre moyen de le faire jusqu'à ce que Java implémente le support des propriétés de style C #.
Subjonctif en anglais.
Oh, attends, tu voulais dire les langages de programmation? Ensuite, utilisez (macro)
dans C pour contourner le préprocesseur #define
sur macro()
. Par exemple, si quelqu'un a #define free(...)
, (free)(...)
ne sera pas la même chose que free(...)
.
VENU _ DE quelqu'un?
JCL Exécution conditionnelle.
//STEP02 EXEC PGM=PROG02,COND=(4,GT,STEP01) .
Cette fonctionnalité vous permet d'exécuter ou non une étape en fonction du code de retour des étapes précédentes. Tout à fait une fonctionnalité vraiment bien.
À l'exception de quelques petites fonctionnalités qui renversent la logique.
D'abord, l'étape ne s'exécute PAS si la condition est vraie.
Deuxièmement, le 4, GT, STEP01 signifie en réalité "si le code de retour de STEP01 est supérieur à 4"
Le tout signifie donc "Ne lancez pas cette étape si le code de retour de STEP01 est supérieur à 4". Quel est le presque mais pas tout à fait la même chose qu'une interprétation naïve "Exécutez l'étape si 4 est supérieure au code de retour de STEP01".
Etant donné que seul le moment où vous examinez sérieusement ces choses-là est environ 2h30 du matin avec un opérateur de nuit effréné à l'autre bout de la ligne, cette double ambiguïté entraîne de graves maux de tête.
Ce n'est pas une fonctionnalité étrange, en fait, cela a un sens total si vous y réfléchissez, mais vous me donnez quand même un moment WTF.
En C++ (et en C #), les sous-classes d'une base ne peuvent pas accéder aux membres privés et protégés sur l'instance de la base.
class Base {
protected:
m_fooBar;
};
class Derived: public Base {
public:
void Test(Base& baseInstance) {
m_fooBar=1; //OK
baseInstance.m_fooBar = 1; //Badness
//This, however is OK:
((Derived&)baseInstance).m_fooBar = 1; //OK
}
};
J'ai construit un langage avec une clause BUT une fois, il y a longtemps.
Le préprocesseur C et ses usages. Métaprogrammation du préprocesseur et utilisation du préprocesseur pour générer du code portable - total mindfcuk.
"dynamique" en C #.
Ruins est la journée de tous ceux qui doivent travailler avec une victime RAD ou python, car Intellisense, la sécurité et le déterminisme de type meurent instantanément lors de la première utilisation du mot-clé "dynamic".
C # a une fonctionnalité appelée "méthodes d'extension", qui est à peu près analogue à Ruby mix-ins - Vous pouvez essentiellement ajouter une méthode à toute définition de classe préexistante (par exemple, vous pouvez ajouter "reverse" ) "à String si vous étiez si incliné). Cela seul suffit - La partie "Bizarre" consiste en ce que vous pouvez ajouter ces méthodes d'extension, avec un corps de méthode et tout, à un interface. D'une part, cela peut être pratique pour ajouter une seule méthode à une série de classes qui ne font pas partie du même arbre d'héritage. D'autre part, vous ajoutez des méthodes détaillées aux interfaces, brisant essentiellement la définition même d'une interface.
Rétrospectivement, le calcul obtenu par FORTRAN est assez étrange. Wikipedia me dit Certains BASIC le surpassent.
Un autre favori célèbre est ALGOL 60 appel par nom passage de paramètre.
Dans J , la plupart des primitives (fonctions a.k.a.) sont monadiques (un argument) ou dyadiques (deux arguments, un à gauche, un à droite). Mais l'amendement primitif prend 3 (je pense que c'est le seul, à part les étrangers). Il est compréhensible que cela prendrait 3, mais cela semble juste ... mal au début.
vector =: i. 10 NB. Vector will be 0 1 2 3 4 5 6 7 8 9
(10) (0) } vector NB. Will yield 10 1 2 3 4 5 6 7 8 9
Je me suis toujours demandé quel était le but de cette fonction dans la classe Math de la bibliothèque Java Core:
static double expm1(double x); // Returns e^x - 1.
Dans J , les étrangers (!:
) sont diverses fonctions regroupées. L'argument de gauche est une catégorie où, comme à droite, il y a souvent (mais pas toujours) des valeurs incrémentielles pour différentes ... choses. Par exemple:
2!: 55 NB. Fermer la console 9!: 10 NB. Définir la précision d'impression 6!: 0 NB. Heure réelle 6!: 2 NB. Temps d'exécution 4!: 3 NB. Scripts chargés
Bien sûr, l’intelligence est de les envelopper, mais vous ne pouvez vous engager que dans la mémoire. BTW, tous ceux-là sont, à bien y penser, triadiques, avec 2 arguments à droite et un à gauche. Aucune de ces solutions ne fonctionnera à moins que vous ne leur donniez un argument final valide.
En PHP, vous devez référencer explicitement les globales et utiliser explicitement this -> pour les variables de classe. Rend le refactoring amusant. Vous ne pouvez pas promouvoir une variable/un argument en tant que membre global ou en tant que classe sans rechercher tous les points d'utilisation.
En C, a[b][c]
est exactement la même chose que c[b[a]]
.
Quel type de données est foo?
SELECT TOP 1
NULL AS foo
INTO
dbo.bar
FROM
sys.columns --trivial
Pourquoi tout va à zéro?
SELECT CAST('' AS int), CAST('' AS datetime), CAST('' AS float)
...sauf ça
SELECT CAST('' AS decimal)
Utilisation par Haskell de Maybe
et Just
. Maybe a
est un constructeur de type qui retourne un type de Just a
, mais Maybe Int
n'acceptera pas simplement un Int
, il doit donc s'agir d'un Just Int
ou Nothing
. Donc, en substance, dans le langage de haskell, Just Int
est à peu près aussi un Int qu'un Apple est une orange. La seule connexion possible est que Just 5
renvoie un type de Maybe Interger
, qui peut être construit avec la fonction Just
et un argument Integer. Cela a du sens mais est aussi difficile à expliquer que théoriquement, quel est le but de haskell, non? Alors, _ Just
vraiment JustKindaLikeButNotAtAll
oui, et Maybe
vraiment un KindaLooksLikeOrIsNothing
, oui encore.
-- Create a function that returns a Maybe Int, and return a 5, which know is definitly Int'able
> let x :: Maybe Int; x = 5;
<interactive>:1:24:
No instance for (Num (Maybe Int))
arising from the literal `5' at <interactive>:1:24
Possible fix: add an instance declaration for (Num (Maybe Int))
In the expression: 5
In the definition of `x': x = 5
> Just 5
Just 5
it :: Maybe Integer
-- Create a function x which takes an Int
> let x :: Int -> Int; x _ = 0;
x :: Int -> Int
-- Try to give it a Just Int
> x $ Just 5
<interactive>:1:4:
Couldn't match expected type `Int' against inferred type `Maybe t'
In the second argument of `($)', namely `Just 5'
In the expression: x $ Just 5
In the definition of `it': it = x $ Just 5
Bonne chance à lire ceci, j'espère que c'est juste.
Dans ColdFusion, les valeurs de texte sont converties automatiquement en différents types de données à des fins diverses. J'ai rencontré un problème étrange où "00A" et "000" étaient en train d'être rendus égaux. Il s’est avéré que ColdFusion interprétait "00A" comme une heure, convertissant en un format de temps numérique et le convertissant en 0. "000" était en cours de conversion en 0. Ils étaient donc considérés comme équivalents. C'est à ce moment-là que j'ai découvert la fonction de comparaison des chaînes.
Il n'y a pas si longtemps, lorsque j'ai découvert le langage C dans ma classe de CS, il était très étrange de voir comment les pointeurs se comportaient. nous venons d'écrire des programmes et devinons ce que ça ferait, jusqu'à ce qu'ils aient le bon comportement
Smalltalk:
Avoir une méthode de classe dans une classe Test, qui renvoie une chaîne constante:
method1
^ 'niko'
Vous devez vous attendre à ce que cette méthode retourne constamment la chaîne 'niko' quoi qu'il arrive. Mais ce n'est pas le cas.
s := Test method1
(Définissez s sur 'niko'.)
s at: 4 put: $i.
(Définissez s sur 'niki'.)
s := Test method1
(Réglez s sur 'niki' à nouveau.)
Donc, ce qui se passe, c'est que la deuxième ligne de code a changé de façon permanente méthode1 pour renvoyer 'niki' plutôt que 'niko', même si le code source de la méthode n'a pas été mis à jour.
opérateur ternaire de Python
En Python, l’opérateur ternaire (exemple C++: bool isNegative = i < 0 ? true : false;
) est disponible en tant que sucre syntaxique:
>>> i = 1
>>> "It is positive" if i >= 0 else "It is negative!"
'It is positive'
>>> i = -1
>>> "It is positive" if i >= 0 else "It is negative!"
'It is negative!'
Ce n'est pas vraiment étrange mais une fonctionnalité. La chose étrange est l’ordre modifié (A si CONDITION sinon B) par rapport à l’ordre (IMO plus logique) en C (CONDITION? A: B).
Les variables implicites\constantes et les constantes mutables en Ruby
try: pass
except: pass
else: pass
finally: pass
Si aucune exception n'a été interceptée, la partie else est exécutée.
Cela a du sens, mais au début, je ne savais vraiment pas ce que ça faisait.
Exemple :
def show_square(string):
try:
n = int(string, 10)
except ValueError:
print "I can't do that, Dave."
else:
print n * n
Les Tcl virtualisent le sens des crochets temporels dans l'interprète sont assez bizarres: http://www.tcl.tk/cgi-bin/tct/tip/233.html
Fondamentalement, cela vous permet d’obliger l’interprète à utiliser une autre source de données temporelles, par exemple. pour exécuter des tests matériels dans un simulateur d’abord et plus tard, il suffit de remplacer les fonctions de la minuterie et d’exécuter les mêmes tests sur la réalité.
Dans awk, les tableaux commencent à l'indice 1, ce qui est le moins déroutant.
En C #, pourquoi n'est-ce pas légal?
public class MyClass<T>
where T: Enum
{
}
Il serait bien de pouvoir ajouter des méthodes d'extension sur Enum avec Func <T> où T serait l'énum que vous étendez afin que vous puissiez obtenir une inférence de type sur cette énumération.
Re le commentaire: Oui, vous pouvez prolonger une énumération réelle, mais voici la différence:
Tu peux le faire:
public static void DoSomethingWithEnum(this Enum e)
{
//do whatever
}
mais que se passe-t-il si vous voulez prendre un Func avec votre méthode qui serait du même type que votre enum:
public static void DoSomethingWithEnum<T>(this T e, Func<T,bool> func )
where T: Enum
{
//do whatever
}
De cette façon, vous pouvez appeler votre méthode comme suit:
DayOfWeek today = DayOfWeek.Monday;
today.DoSomethingWithEnum(e => e != DayOfWeek.Sunday);
ou quelque chose comme ça. Vous avez l’idée… C’est impossible, et je ne sais pas pourquoi….
En JavaScript, 2.0 - 1.1 = 0.8999999999999999
. Ceci est le résultat de l'implémentation de floats dans la spécification, donc ce sera toujours comme ça.
Appeler/cc. Call/cc passe une fonction représentant le reste du programme à son corps.
Dans MySQL, les comparaisons de chaînes ne respectent pas la casse.
> SELECT * FROM blah WHERE foo = 'BAR';
> SELECT * FROM blah WHERE foo = 'Bar';
> SELECT * FROM blah WHERE foo = 'bAr';
Sont tous équivalents. Non seulement ils correspondront à toute valeur de foo qui ressemble à 'bar' (par exemple, si foo = 'bar', elle correspondra à BAR, BAR, BAR, etc.).
En C #, le code suivant génère une erreur du compilateur "Impossible de convertir un groupe de méthodes en délégué". Bien que la logique derrière soit raisonnable, cela me semble toujours étrange.
control.BeginInvoke(delegate { DoSomething(); });
Dans SQL Server, vous pourriez vous retrouver avec une mauvaise surprise si vous utilisez select *
dans votre code de production. Utiliser select *
n'est pas considéré comme une bonne pratique, mais il est bon de connaître certains comportements intéressants.
Voir la question comportement "choisir * du tableau" vs "choisir le colA, le colB, etc. du tableau" dans SqlServer2005 pour plus de détails
Dans ColdFusion
Struct (aussi appelé Java HashMap) est transmis par référence.
Vous auriez pensé qu'un autre type de données se comporte comme Java ...
Un tableau est transmis par valeur, wtf!
La liste est simplement un ancienne chaîne séparée par des virgules!
Un fichier source Java peut se terminer par le caractère \u001a
(control-Z).
Eh bien, la première chose qui m’est venue à l’esprit était "noop", mon cerveau a fait la même chose quand j’en suis arrivé à le comprendre!
cela m'a rendu magnifique
#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}
Go's Iota pseudo-constante:
type ByteSize float64
const (
_ = iota; // ignore first value by assigning to blank identifier
KB ByteSize = 1<<(10*iota); MB; GB; TB; PB; YB;
)
décalage;
parfois, vous le voyez dans la toute première ligne d'une méthode Perl pour obtenir une lecture du pointeur personnel
Libellé des instructions break et continue en Java. .
Ils vous permettent de sortir de plusieurs blocs de contrôle en une seule pause.
Je ne sais pas si c'est toujours vrai, mais nous avons découvert par hasard que VS FORTRAN (66 ou 77) ne prendrait pas en charge la récursivité. La récursion était accidentelle et notre F77 par défaut la supportait magnifiquement, mais lorsque nous avons transféré la source sur un serveur IBM - Whatta.
Perl
my %h1 = map { $_ => 1 } qw/foo bar baz/; // construct an 'is_member' type lookup table
my %h2 = map { "$_" => 1 } qw/foo bar baz/;
la deuxième ligne est une erreur de syntaxe même si, même pour un programmeur Perl expérimenté, il semble que ce soit la même chose. Perl essaie toujours de faire ce que vous voulez dire, pas ce que vous avez dit.
Déclaration de rendement en C #, pas étrange mais très utile.
http://msdn.Microsoft.com/en-us/library/9k7k7cf0 (VS.80) .aspx
En voici un sur le python:
>>> print 07
7
>>> print 08
File "<stdin>", line 1
print 08
^
SyntaxError: invalid token
N'est-ce pas une beauté?
Particulièrement impensé quand on pense à la façon dont les écritures écrites par l'homme ont l'effet suivant:
datetime.date(2010,02,07) # ok
datetime.date(2010,02,08) # error!
(la raison en est que 0x
est interprété comme octal, donc print 010
imprime 8
!)
Je suis tombé sur celui-ci en essayant de trouver une MACRO qui n'avait aucun sens, mais qui fonctionnait quand même. Ceci est vrai pour objective-c mais pourrait l'être aussi pour d'autres versions de C (ou au moins le compilateur gcc)
NSString *oneString = @"This " @"is " @"just " @"one " @"normal " @" string";
équivaut à
NSString *oneString = @"This is just one normal string";
C'est également vrai pour les chaînes de style C
char* str = "this " "also " "works";
En Python, du moins pour moi, c'était très wft! la première fois que je l'ai vu:
>>> "ja " * 5
'ja ja ja ja ja '
Vous pouvez multiplier les chaînes! WTF ??
PS: Je pense que c'est parce que x * n
signifie: n times x
donc, 5 times "ja "
est "ja ""ja ""ja ""ja ""ja "
et parce que vous pouvez concaténer des chaînes comme ceci:
>>> "ja ""ja ""ja ""ja ""ja "
'ja ja ja ja ja '
Que deux codes ont le même résultat (et sont peut-être identiques)
En Java, il existe une certaine incohérence quant à la manière dont Strings gère l’opérateur == en fonction de sa construction.
String a = "Hello";
String b = "Hello";
System.out.println(a == b ); // prints true.
String c = new String("Hello");
String d = new String("Hello");
System.out.println(c == d ); // prints false
Dans Scheme, il y a no identifiants réservés. Donc, l'expression suivante est évaluée à 1:
((lambda (lambda) lambda) (let ((let 1)) let))
Notez qu'il existe une restriction sur les définitions dans une étendue donnée: aucune définition ne peut redéfinir un identificateur utilisé pour définir des identificateurs dans cette étendue. Par conséquent, voici une erreur de syntaxe:
(begin (define define 1) define)
En unité,
GameObject.Find("MyObject")
retournera votre objet normalement. Cependant, si vous faites quelque chose comme ça:
GameObject.Find("MyObject").active = false;
//do other stuff
if (GameObject.Find("MyObject").active)
{
//do stuff
}
Ensuite, vous obtiendrez une référence nulle. Dans Unity iPhone, ce code fonctionnera souvent correctement sous l'éditeur, mais provoquera un SIGBUS lorsqu'il est exécuté à partir de l'iPhone. Le problème est que GameObject.Find () ne localisera que les objets actifs. Ainsi, même si vous ne faites que vérifier s'il est actif, vous appelez effectivement if (null.active).
Pour que cela fonctionne correctement, vous devez le stocker avant de le rendre inactif.
GameObject obj = GameObject.Find("MyObject");
obj.active = false;
//do other stuff
if (obj.active)
{
//do stuff
}
C'est peut-être mieux une pratique de toute façon, mais la manière dont Unity traite les objets inactifs en général est assez étrange. Il semble décharger une grande partie de l'objet inactif (textures, etc.), mais pas la totalité, de sorte que les objets inactifs peuvent toujours consommer beaucoup de mémoire.
Et encore Haskell:
Dans Haskell, vous pouvez gérer un fichier de taille arbitraire, comme s'il s'agissait d'un simple fichier String
. Le fichier ne sera lu que si la chaîne est réellement utilisée. En raison de l'incroyable paresse de Haskell, un programme comme celui-ci s'exécutera dans un espace constant, quelle que soit la taille du fichier:
main = interact (>>= \x -> if x == '\n' then "\r\n" else [x])
(Ce programme convertit un fichier de stdin en stdout et remplace LF par CRLF, l'entrée interact
est l'intégralité du stdin en une fonction et déplace la sortie vers stdout.)
Cette paresse peut également causer des problèmes, car si vous fermez un descripteur de fichier, vous ne pouvez pas être complètement sûr, que Haskell soit paresseux ait déjà analysé toutes les données qu'il contient.
Ceci n’a rien d’étrange ni de surprenant, mais c’est est quelque chose qui m’a toujours fait dire WTF:
Respect de la casse dans la syntaxe ou dans les noms d'identifiant.
La plupart des langues qui l'ont semblent juste l'avoir parce que C l'a. Il n'y a pas de bonne raison pour cela.
Ce programme C affiche un résultat différent sur x86 vs x86-64:
#include <stdio.h>
int main (void)
{
long a = -1;
unsigned b = 1;
printf ("%d\n", a > b);
return 0;
}
en Java
String("aaa")==String("aaa") //false
//you need to use
String("aaa").equals(String("aaa")) // true
С #:
var a = Double.Parse("10.0", CultureInfo.InvariantCulture); // returns 10
var b = Double.Parse("10,0", CultureInfo.InvariantCulture); // returns 100
Dans la culture invariante, la virgule n'est pas un symbole décimal, mais un séparateur de groupe.
Comme je le sais, c'est une erreur courante pour les programmeurs débutants de certains pays.
En C++, je trouve étrange et désagréable que "virtuel" MI (héritage multiple) permette à la hiérarchie de classe "losange-shape" de "fonctionner"
A : Base class, e.g. "Object" B, C: both derive (virtually or not) from Object and D: derives from both B and C
Problème: l'héritage "normal" fait en sorte que D soit 2 types de A. ambigus. "Virtuel" L'IM rétrécit B de A et C de A en un seul objet partagé de base.
Ainsi, même si votre roue est un objet et que votre roue avant gauche est une roue et que votre voiture hérite de quatre types de roues, votre voiture n’est encore qu’un type d’objet avec un MI virtuel. Sinon, votre voiture n'est pas un objet, mais 4 objets roulants.
Il s’agit d’une fonctionnalité linguistique qui récompense les classes de mauvaise qualité, punit les rédacteurs de compilateur et vous laisse vous demander, au moment de l’exécution, où diable se trouve l’objet - et si un bagage MI virtuel a été égaré.
Si vous avez vraiment besoin du motif en losange dans votre hiérarchie de classe, vous pouvez le réaliser avec un MI normal et un "AProxy" qui délègue à la base A simple.
A : Base class, e.g. "Object" AProxy: Base class, constructs with other A to bind to B : derives from A C : derives from AProxy D : derives from both B and C (passing B's A to C's AProxy at construction)
Cela nécessite un peu plus de travail pour ceux qui aiment vraiment les diamants MI et laisse le reste d'entre nous en paix avec un ensemble de fonctionnalités linguistiques plus facile à gérer.
Pour ceux qui n'ont jamais travaillé avec COBOL, il s'agit d'une ligne de code commune, mais elle ne fait pas ce que vous pensez peut-être.
PIC XXX
En voici un que j'ai trouvé bizarre:
En C/C++, vous pouvez avoir autant de points-virgules que vous le souhaitez au moins dans MS C++:
int main(void)
{
cout<<"Hello World";;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;
return 0;;;;;;;;;;;;;;;;;;;;;;;
}
PHP (encore?)
D'abord: (unset)
transtypage.
$a = 1;
$b = (unset)$a;
var_dump($a); // 1
var_dump($b); // NULL
Utilisation: http://www.php.net/manual/fr/language.types.type-juggling.php#89637
Deuxièmement: différence entre = NULL
et la fonction unset()
.
$c = 10;
$d = &$c;
$c = NULL;
var_dump($c); // NULL
var_dump($d); // NULL
$e = 10;
$f = &$e;
unset($e);
var_dump($e); // NULL
var_dump($f); // 10 - WTF?
En C,
int x = 1;
int y = x++ + ++x;
printf("%d", y);
Est ambigu, ce qui est imprimé dépend du compilateur. Le compilateur peut stocker la nouvelle valeur de x ++ avant que ++ x soit évalué ou à la fin de l'instruction.
En PHP:
<?php
$o = new stdClass;
echo count($o);
?>
..prints 1. Jamais compris pourquoi.
Delphi ne s’intéresse pas au typecast comme "Word" et lira en dehors du tableau arr [0..65535] où pos = 65535: arr[Word(pos + 10)]