Je vais répondre dans le désordre, ça évitera les redites.
Je ne comprends pas ce que ça veut dire (est-ce que parler de « services » est une façon cachée de parler d'interfaces ?).
Services, interface (au sens Java ou CORBA), fonctions, méthodes, comportements, ça représente à peu de choses près la même chose : les messages auxquels l'objet peut répondre.
Ca veut dire quoi séparer proprement ? Je vais pas m'amuser à dupliquer (proxy) pour le plaisir d'avoir un beau design qui plait aux théoriciens.[...] existantes.
Cela dépend de ce que tu veux au final. P.ex. si tu veux pouvoir réutiliser la partie calcul avec une UI totalement différente ou si tu es à peu près sûr que cela ne te reservira jamais.
Dans tous les cas tu réutilises les classes existantes, mais pas de la même façon, donc pas avec les mêmes avantages/inconvénients.
En gros, tu as trois façons :
1. une seule hiérarchie ou tu mélanges tout,
- avantage : tout au même endroit ;
- inconvénients : tout au même endroit, pas de modularité, ce n'est plus du couplage fort, c'est de la fusion ;
- avis personnel : vilain, caca, pouah, pas glop !
2. une hiérarchie calcul et une hiérarchie UI, avec les classes de l'UI qui utilisent (agrégation) les classes calcul,
- A : couplage faible entre calcul et UI ;
- I : une indirection supplémentaire (pour accéder à une donnée, il faut passer par l'agrégé ) ;
3. une hiérarchie calcul et une hiérarchie UI, avec les classes de l'UI qui héritent des classes de calcul,
- A : couplage plus faible que 1. ;
- I : mais plus fort que 2. ;
- autre A : un peu moins d'indirections ;
- autre I : confusion possible entre utiliser et hériter.
Je pense qu'hériter au lieu d'utiliser est une mauvaise chose car ce sont deux mécanismes conceptuellement différents. Ce que tu proposes c'est d'utiliser l'héritage à la place de l'agrégation pour
- raccourcir le code (mauvaise raison) ;
- simuler un mixin (meilleure raison mais encore faut-il :
1. le savoir ;
2. le noter (commentaires)).
Maintenant, tout ce que je dis ne sert à rien et n'avancera à rien si, comme pourrait sembler le faire penser l'exemple Laguna, tu ne fais pas la différence entre hériter et utiliser.
Europe et l'Asie sont sur la même plaque tectonique (Eurasie).
Le Japon est à la limite est de la plaque Eurasie, à côté de la plaque Philippine. Enfin presque, il semblerait que l'est du Japon soit sur la plaque Okhotsk et l'ouest sur la plaque Amour (Amurian en anglais), mais on est pas encore sûr si ce sont des plaques ou des sous-plaques.
La Turquie fait aussi partie de la plaque Eurasie.
On remarquera qu'il y a quelques différences (notamment la séparation entre Amérique du nord et Eurasie, bien notée comme arbitraire sur la 3e, et l'absence de plaques « mineures », comme Okhost et Amour).
Ça, c'est maintenant. Mais les monts Oural¹ ont été formés à l'époque de la collision de la Laurasie (Amérique du nord + Eurasie) avec la Sibérie. Ils sont donc à peu près à l'emplacement de la collision donc à l'ancienne limite des deux plaques.
¹ : d'ailleurs, abbaturk parle du Caucase mais pas de l'Oural. L'Oural est la limite est de l'Europe, le Caucase la limite sud-est, le reste des limites, c'est de l'eau.
Mon commentaire mal ficelé, c'était surtout que les propos d'abbaturk ne veulent pas dire grand'chose, que les plaques se sont soudées et déchirées plusieurs fois et que savoir si Trifouillis lès Coincoin a toujours été sur telle ou telle plaque est de la connerie.
Donc :
- les limites de l'Europe ont été fixées par les Grecs alors qu'ils ne connaissaient même pas la géographie de leur péninsule ;
- pour des raisons historiques (la petite histoire), les géographes ont conservé ces limites ;
- pour des raisons politiques, les politiques ont conservé ces limites (pour justifier des rapprochements ou des différenciations) ;
- quelques uns essaient vainement de s'accrocher à ces limites en les justifiant par quelques faits scientifiques.
Voilà. Maintenant on pourrait parler de culture et d'histoire pour justifier des différences de traitement mais je n'ai pas envie d'écrire un bouquin qui finirait par « oui et non ». En plus, ces commentaires sont déjà largement hors propos.
Ouaip, Kissinger a réussi à obtenir le Nobel de la paix en 1972 pour avoir mis fin à la guerre Vietnam. Sauf que la guerre du Vietnam s'est terminée en 1975...
(D'ailleurs, son co-lauréat, le prince Sihanouk, a refusé de se déplacer pour cette mascarade.)
Toujours, c'est vite dit.
Disons au moins 270 Ma (séparation de la pangée), voire 550 Ma (le monocontinent d'avant), ou encore le précédent (je n'ai plus mes signets géologiques sous le coude)...
Ok. Ça va être long alors je coupe un peu. J'espère ne rien oublier...
Pourquoi ?
Je suppose que tu veux savoir pourquoi héritage structurel et héritage comportemental sont différents (si c'est « pourquoi l'héritage multiple pose problème », j'en reparle plus bas).
L'héritage de structure, c'est lorsque l'on hérite des composants, des attributs, au niveau du modèle (donc lorsque l'on est proche du monde réel). Conceptuellement, il est très rare (même dans les cas d'école) d'avoir besoin d'hériter de plusieurs structures.
P.ex. un Point2DColoré hérite d'un Point2D sa structure (en gros, x et y). Mais un Rectangle ne devrait pas hériter d'un Point2D : un rectangle peut être défini de bien des manières (= 2 points, = 1 point + largeur + hauteur, etc.) mais on ne peut pas dire « un rectangle est un point ».
L'héritage de comportement, c'est lorsque l'on hérite de la façon de se comporter, des services donnés.
P.ex. un Point2DTranslatable promet l'interface Translatable, tout comme un RectangleTranslatable.
La différence entre classe et interface tient aussi de la différence entre type et classe.
P.ex., une interface qui pour moi est simple et qui n'est incontestablement pas une classe, c'est Comparable. Deux entiers sont comparables entre eux, deux voitures peuvent être comparables entre elles (p.ex. suivant un ordre de préférence qu'aurait le programmeur), mais un entier n'est pas une voiture et une voiture n'est pas un entier. Par contre, grâce à ce type Comparable, je peux écrire une fonction de tri d'un tableau d'objets de ce type et je pourrais utiliser cette fonction sur un tableau de voitures ou un tableau d'entiers sans avoir à redéfinir la fonction et, ce qui est important¹, avec un typage fort.
¹ : c'est important ici car si le typage fort n'est pas dans le langage, alors les concepts ne sont plus les mêmes et la différence type / classe ne sert plus à rien.
Pour éclairer un peu la différence type / classe, une variable a un type (en Java, C++...), et un objet a une classe et des types.
Quand je me heurte concrètement à ce problème[...] l'API.
Oui. P.ex. si je propose une interface Coloré pour mes points et rectangles : se pose le problème de l'attribut couleur qui a de fortes chances de se retrouver dans toutes les classes promettant le service.
C'est parce que :
- soit il fallait prévoir dès le début qu'un objet géométrique pouvait avoir une couleur (pas deux classes : Point2D et Point2DColoré mais seulement ObjetGéoColoré et les autres qui en héritent) ;
- soit il faut utiliser un autre mécanisme, absent des primitives Java (mais que l'on peut simuler par délégation), les Mixin ou les Traits.
C'est a dire ? L'héritage en diamant me semble poser un problème dans l'implémentation du langage, pas pour le programmeur, je me trompe ?
Oui. Le classique cas: classe A avec attribut a, classe B et C qui héritent de A et classe D qui hérite de B et C. L'attribut a est hérité deux fois par D. Comment gérer ça ? Qu'est-ce que cela peut bien signifier ?
Parfois, le programmeur voudrait deux a, parfois il n'en veut qu'un. C'est donc aussi un problème dans la tête du programmeur.
D'autre part je continue à ne pas apprécier la délégation qui impose du code "dupliqué" au kilomètre.
Des automatismes sont maintenant utilisés pour simplement noté qu'un attribut est en fait délégué et ses fonctions sont « proxysées » automatiquement.
C'est un exemple rapidement fait [...]
C'est un peu le problème avec tous les exemples que l'on me sort pour dire que l'héritage multiple est plus utile que néfaste ;o)
D'ailleurs quelle est vraiment la différence ave le fait d'hériter d'une classe et d'implémenter une ou plusieurs interfaces ?
Aucune et plein.
Une interface est une classe abstraite, donc c'est une classe, donc on en hérite.
Mais cela correspond à un héritage de comportement, pas de structure. (Voir plus haut type / classe...)
Je vais te donner un autre cas concr[e]t [...] Est-ce une mauvaise conception ? A cause du manque de l'héritage multiple, je ne sais pas comment faire ça élégamment en Java.
Oui, c'est une mauvaise conception : le modèle de calcul (= les classes qui servent à représenter tes données géométriques) doit être découplé du modèle de dessin (UI).
C'est le MVC.
Ok. Tu vas me dire que tu dois dupliquer encore ton arbre d'héritage mais c'est à toi de choisir :
- ou tu sépares proprement application et interface (c'est-à-dire que tu fais un modèle pour le calcul, un modèle-proxy pour donner à l'UI et une UI (avec ses objets à elle : widgets de toutes sortes)) ;
- ou tu ne fais qu'un modèle qui mélange à la fois les structures et les services pour le calcul et pour l'UI.
Uniquement parce que dans mon exemple tu suggères de remplacer des classes par des instances ?
Tu admettras quand même que les concepts d'instance et de classe sont suffisamment distincts pour faire que, pour un même modèle, seulement un seul peut s'appliquer (c.-à-d. que tu n'as pas le choix entre l'un ou l'autre : il y en a un qui s'applique et l'autre qui ne veut rien dire).
Est-ce que tu peux m'expliquer pourquoi il est conceptuellement correct d'avoir un héritage simple et de l'implémentation d'interface(s), mais pas correct d'avoir un héritage multiple ? (en fait cette question se rapproche beaucoup de ma question du paragraphe précédent)
Conceptuellement, il y a un problème dans le cas du diamant : que veut dire hériter de deux fois la même structure ?
Conceptuellement, l'héritage multiple englobe aussi les Mixin. (Ruby les différencie en utilisant des modules, j'aurais peut-être préféré un mot-clef mixin.)
Donc, je ne dis pas que ce n'est pas correct, mais, comme on est parfois obligé lorsque l'on enseigne des concepts complexes, on exagère un peu les mises en garde (parce que tout le monde se croit assez malin pour les transgresser) en en faisant des interdictions (puisque, de toute façon, on peut s'en passer).
Donc, comme la plupart des problèmes de l'héritage multiple (tous ?) se posent pour l'héritage de structure multiple, une solution pour les éviter est de l'empêcher. Par contre, l'héritage multiple de services ne pose pas de problème (si deux services ont le même nom, ils doivent représenter la même chose, sinon il y a un problème de nommage dans le modèle).
Enfin, pour mettre en perspective la pensée que l'héritage multiple est un symptôme de mauvaise conception [...]
Je pense en fait que l'on est en train d'arriver à des concepts plus précis.
Au départ, il n'y a que l'objet, tout est objet, blabla... Mais on s'est vite rendu compte qu'il y avait plein de concepts différents et on a pas encore fini de les différencier correctement. On différencie maintenant héritage de structure et de services, on parle d'aspects, de mixins... Il faut encore poser tout ça pour que ça ressemble à quelque chose.
[1] je rapproche [...]
1. Le GC de Java fonctionne aussi avec compteur de références. Je pense que tu voulais plutôt dire que le nettoyage est, dans un cas, seulement fait lorsqu'il y a besoin de place, et dans l'autre cas, dès que la référence arrive à zéro.
2. Pour les histoires de propreté avec les E/S etc., il est à mon avis bien plus propre de le faire explicitement (et même dans le finally d'un try pour être bien sûr que c'est fait).
Non, on est jamais sûr que finalize sera appelée. Cette méthode n'est appelée _que_ lorsque la VM veut réutiliser la mémoire utilisée par un objet qui n'est plus référencé. Si la VM ne réutilise pas la mémoire (p.ex. si elle termine ou si elle peut augmenter la mémoire allouée auprès du SE), finalize ne sera jamais appelé.
Dans ton problème, tu prends la relation d'héritage à chaque fois que tu peux dire « est-un ». C'est une simplification qui est souvent utilisée pour enseigner l'OO mais rarement expliquée comme telle.
Java a été conçu après 20 ans d'expériences en POO, après que l'on a pu conceptualiser pas mal de zones d'ombre. Et, à ce moment, l'on s'était rendu compte que l'héritage multiple posait beaucoup de problèmes et qu'il fallait faire une différence entre l'héritage de structure (classes) et l'héritage de comportements (interfaces). On s'est aussi rendu compte que la majorité des problèmes de l'héritage multiple sont dus à l'héritage multiple de structures (problèmes de l'héritage en diamant, p.ex.). On s'est aussi rendu compte que les autres cas d'héritage multiple sont relativement rares (comparativement aux ennuis) et facilement contournables par délégation.
Maintenant, on s'apperçoit qu'il y a d'autres problèmes en POO, comme les aspects p.ex.
Pour en revenir à ton exemple précis (que j'ai eu du mal à obtenir hier, d'où une réponse seulement aujourd'hui), tu fais plusieurs choix discutables, p.ex. que Laguna est une classe et que Renaut est une classe. Voiture est bien une classe, mais Renault est une instance de la classe Constructeur et Laguna une instance de la classe Modèle. Voiture aura donc deux attributs : constructeur et modèle.
Alors tu me répondras : c'est de la délégation, c'est plus joli avec de l'héritage. Mais l'héritage n'a rien à voir dans ces relations. Le fait que tu puisses remplacer de l'utilisation (composition/aggrégation) par de l'héritage et que cela soit plus court à écrire n'est pas une raison pour le faire. Conceptuellement, ça ne tient pas.
Je crois que ce serait plutôt dans cet ordre de préférences là :
1. avoir un pilote libre fourni par le constructeur ;
2. avoir les spécs pour pouvoir faire un pilote ;
et, au pire, certains s'accomoderaient plus ou moins temporairement,
3. avoir un pilote fourni par le constructeur.
Avoir les spécs, ou plutôt l'API, est une conséquence du 1 (si on a un pilote libre, pas trop crypté, on peut l'étudier et le modifier si besoin¹).
Et il n'y a pas trop de raisons que le constructeur ne fournisse pas de pilote pour son matériel à lui qu'il a développé lui-même.
¹ : si le pilote constructeur fonctionne, on n'a pas forcément _besoin_ de le modifier (ok, un hacker le fait parce qu'il peut le faire, mais l'histoire de RMS, c'était parce que le programme de son imprimante était pourrave).
La diffeernce avec la France, c'est que tu peux aller dans de tres bonnes ecoles en France sans devoir vendre tes enfants, ce qui donne une chance a bcp plus de gens.
Ça n'est vrai qu'en théorie. L'« ascenseur social » est bloqué. Les enfants d'ouvriers¹ ont quand même beaucoup plus de mal. (Et je ne parle pas des personnes issues de l'immigration.)
Juste pour répondre à plusieurs commentaires sur les moyens de gagner de l'argent avec des LL. Certains semblent postuler que les sources sont distribuées à tous. Or, je veux juste rappeler que la GPL (p.ex.) ne demande pas que l'on distribue le source à tous mais seulement à ceux à qui l'on a distribué le binaire (et encore, seulement à ceux qui le demandent).
On peut donc très bien faire payer le logiciel et de ne distribuer le source qu'à ses clients payants. Le seul moyen de perdre cette source de brouzoufs est que l'un des clients utilise son droit à redistribuer le logiciel (et ses sources) pour moins cher (voire gratuitement).
Or, il existe peu de logiciels qu'un client prendra la peine de redistribuer. Il existe aussi peu de clients qui le feront. Il faut mesurer le bénéfice que le client a à redistribuer.
Faut dire aussi que c'est pas facile d'écrire un mot sur trois en (suisse-)allemand, un mot sur trois en (suisse-?)italien et un mot sur trois en français(^Wromand)...
Katz ne compare pas RoR avec Zope, ni les bibliothèques de Ruby avec celles de Python.
Il explique simplement que le principe exposé par Graham de bottom-up design (ci-après BUD) est en fait un des principes de Ruby et de Lisp.
RoR est une sorte de « Ruby++ pour le web ».
Il dit aussi que c'est pour cela que RoR est bien : c'est du Ruby et, en même temps, c'est plus que du Ruby.
Il donne Zope 2 comme contre-exemple : c'est en Python mais ce n'est pas du Python. Il pense que c'est pour cela que Zope a eu des problèmes et que Zope X3 a été lancé.
Voilà. La réponse à la question posée dans le titre (Est-ce que RoR aurait pu être écrit sans Ruby ?) est non, car pas de BUD, pas de RoR et Ruby permet le BUD et oui, car il n'est pas le seul (mais c'est quand même 'achetement pratique en Ruby ;o).
Sinon,
awk "BEGIN {FS=\";\"} { printf \"INSERT INTO table (c1, c2...) VALUES ('%s', '%s'...);\n", \$1, \$2} ' monfichier | sqlite mabase
marche aussi.
(Étant donné qu'on connaît déjà forcément le nombre de champs (colonne1...), on est pas obligé de jouer avec sed pour ajouter les ' ' autour des valeurs.)
Ne pas avoir un compilateur est quand même moins grave que de n'avoir que du binaire.
Si la documentation du langage a aussi été conservée mais que l'on a plus de compilateur, il ne sera sûrement même pas nécessaire de refaire un compilateur mais seulement un traducteur.
Le SE et la « machine compatible » ne sont pas non plus indispensables avec un traducteur/interprète/machine virtuelle que l'on peut concevoir à partir de la doc du langage.
Avec un binaire, ben il faut un émulateur _qui existe_ ou, pire, un décompileur (ce qui donnera un code imbitable et très difficile à modifier/reprendre).
[^] # Re: pourquoi les videos sont toujours sous mac ?
Posté par Sylvain Sauvage . En réponse au journal rails: un module d'identification. Évalué à 1.
Le QuickTime, ça pue.
# sondage
Posté par Sylvain Sauvage . En réponse au journal Mon fils est-il un hacker ?. Évalué à 10.
Les filles deviennent majorettes...
[^] # Re: Craintes, espoirs
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 2.
Croix : Ensemble formé de deux branches ou de deux éléments qui se coupent à angle plus ou moins ouvert, généralement à angle droit.
Croient : 3e pers. du pluriel du verbe croire.
Utiliser « croix » pour « croire » lorsqu'il s'agit de religion, je trouvais ça amusant.
Sur le fond, je ne reviendrai pas sur les notions de preuve et de réfutation...
[^] # Re: Mes deux centimes ...
Posté par Sylvain Sauvage . En réponse au journal Repenser les langages et le développement logiciel. Évalué à 3.
Services, interface (au sens Java ou CORBA), fonctions, méthodes, comportements, ça représente à peu de choses près la même chose : les messages auxquels l'objet peut répondre.
Cela dépend de ce que tu veux au final. P.ex. si tu veux pouvoir réutiliser la partie calcul avec une UI totalement différente ou si tu es à peu près sûr que cela ne te reservira jamais.
Dans tous les cas tu réutilises les classes existantes, mais pas de la même façon, donc pas avec les mêmes avantages/inconvénients.
En gros, tu as trois façons :
1. une seule hiérarchie ou tu mélanges tout,
- avantage : tout au même endroit ;
- inconvénients : tout au même endroit, pas de modularité, ce n'est plus du couplage fort, c'est de la fusion ;
- avis personnel : vilain, caca, pouah, pas glop !
2. une hiérarchie calcul et une hiérarchie UI, avec les classes de l'UI qui utilisent (agrégation) les classes calcul,
- A : couplage faible entre calcul et UI ;
- I : une indirection supplémentaire (pour accéder à une donnée, il faut passer par l'agrégé ) ;
3. une hiérarchie calcul et une hiérarchie UI, avec les classes de l'UI qui héritent des classes de calcul,
- A : couplage plus faible que 1. ;
- I : mais plus fort que 2. ;
- autre A : un peu moins d'indirections ;
- autre I : confusion possible entre utiliser et hériter.
Je pense qu'hériter au lieu d'utiliser est une mauvaise chose car ce sont deux mécanismes conceptuellement différents. Ce que tu proposes c'est d'utiliser l'héritage à la place de l'agrégation pour
- raccourcir le code (mauvaise raison) ;
- simuler un mixin (meilleure raison mais encore faut-il :
1. le savoir ;
2. le noter (commentaires)).
Maintenant, tout ce que je dis ne sert à rien et n'avancera à rien si, comme pourrait sembler le faire penser l'exemple Laguna, tu ne fais pas la différence entre hériter et utiliser.
[^] # Re: USSR
Posté par Sylvain Sauvage . En réponse au sondage Nombre de pays où je suis passé :. Évalué à 2.
Mais que c'est-il donc passé en 1989 ?
[^] # Re: sirop
Posté par Sylvain Sauvage . En réponse à la dépêche Attribution des prix IgNobel 2005. Évalué à 4.
[^] # Re: Ils sont vraiment pathétiques....
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 2.
(À moins que ce ne soit Autant en emporte les hommes.)
[^] # Re: Craintes, espoirs
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 3.
Lapsus ?
[^] # Re: sirop
Posté par Sylvain Sauvage . En réponse à la dépêche Attribution des prix IgNobel 2005. Évalué à 8.
[^] # Re: Turquie
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 8.
Le Japon est à la limite est de la plaque Eurasie, à côté de la plaque Philippine. Enfin presque, il semblerait que l'est du Japon soit sur la plaque Okhotsk et l'ouest sur la plaque Amour (Amurian en anglais), mais on est pas encore sûr si ce sont des plaques ou des sous-plaques.
La Turquie fait aussi partie de la plaque Eurasie.
Voir les plaques tectoniques actuelles, p.ex. là :
http://www.geologie.ens.fr/~vigny/tecto-f.html(...)
http://fr.wikipedia.org/wiki/Image:Tectonique_plaques001.png(...)
http://www.ggl.ulaval.ca/personnel/bourque/s1/1.17.gif(...)
On remarquera qu'il y a quelques différences (notamment la séparation entre Amérique du nord et Eurasie, bien notée comme arbitraire sur la 3e, et l'absence de plaques « mineures », comme Okhost et Amour).
Ça, c'est maintenant. Mais les monts Oural¹ ont été formés à l'époque de la collision de la Laurasie (Amérique du nord + Eurasie) avec la Sibérie. Ils sont donc à peu près à l'emplacement de la collision donc à l'ancienne limite des deux plaques.
¹ : d'ailleurs, abbaturk parle du Caucase mais pas de l'Oural. L'Oural est la limite est de l'Europe, le Caucase la limite sud-est, le reste des limites, c'est de l'eau.
Mon commentaire mal ficelé, c'était surtout que les propos d'abbaturk ne veulent pas dire grand'chose, que les plaques se sont soudées et déchirées plusieurs fois et que savoir si Trifouillis lès Coincoin a toujours été sur telle ou telle plaque est de la connerie.
Donc :
- les limites de l'Europe ont été fixées par les Grecs alors qu'ils ne connaissaient même pas la géographie de leur péninsule ;
- pour des raisons historiques (la petite histoire), les géographes ont conservé ces limites ;
- pour des raisons politiques, les politiques ont conservé ces limites (pour justifier des rapprochements ou des différenciations) ;
- quelques uns essaient vainement de s'accrocher à ces limites en les justifiant par quelques faits scientifiques.
Voilà. Maintenant on pourrait parler de culture et d'histoire pour justifier des différences de traitement mais je n'ai pas envie d'écrire un bouquin qui finirait par « oui et non ». En plus, ces commentaires sont déjà largement hors propos.
[^] # Re: Craintes, espoirs
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 3.
(D'ailleurs, son co-lauréat, le prince Sihanouk, a refusé de se déplacer pour cette mascarade.)
[^] # Re: Turquie
Posté par Sylvain Sauvage . En réponse à la dépêche Brevets logiciels : la Commission Européenne revient à la charge. Évalué à 2.
Disons au moins 270 Ma (séparation de la pangée), voire 550 Ma (le monocontinent d'avant), ou encore le précédent (je n'ai plus mes signets géologiques sous le coude)...
[^] # Re: Cessons
Posté par Sylvain Sauvage . En réponse au journal Un pro-Microsoft à l'économie. Évalué à 7.
Quelle patience !
[^] # Re: Mes deux centimes ...
Posté par Sylvain Sauvage . En réponse au journal Repenser les langages et le développement logiciel. Évalué à 7.
Je suppose que tu veux savoir pourquoi héritage structurel et héritage comportemental sont différents (si c'est « pourquoi l'héritage multiple pose problème », j'en reparle plus bas).
L'héritage de structure, c'est lorsque l'on hérite des composants, des attributs, au niveau du modèle (donc lorsque l'on est proche du monde réel). Conceptuellement, il est très rare (même dans les cas d'école) d'avoir besoin d'hériter de plusieurs structures.
P.ex. un Point2DColoré hérite d'un Point2D sa structure (en gros, x et y). Mais un Rectangle ne devrait pas hériter d'un Point2D : un rectangle peut être défini de bien des manières (= 2 points, = 1 point + largeur + hauteur, etc.) mais on ne peut pas dire « un rectangle est un point ».
L'héritage de comportement, c'est lorsque l'on hérite de la façon de se comporter, des services donnés.
P.ex. un Point2DTranslatable promet l'interface Translatable, tout comme un RectangleTranslatable.
La différence entre classe et interface tient aussi de la différence entre type et classe.
P.ex., une interface qui pour moi est simple et qui n'est incontestablement pas une classe, c'est Comparable. Deux entiers sont comparables entre eux, deux voitures peuvent être comparables entre elles (p.ex. suivant un ordre de préférence qu'aurait le programmeur), mais un entier n'est pas une voiture et une voiture n'est pas un entier. Par contre, grâce à ce type Comparable, je peux écrire une fonction de tri d'un tableau d'objets de ce type et je pourrais utiliser cette fonction sur un tableau de voitures ou un tableau d'entiers sans avoir à redéfinir la fonction et, ce qui est important¹, avec un typage fort.
¹ : c'est important ici car si le typage fort n'est pas dans le langage, alors les concepts ne sont plus les mêmes et la différence type / classe ne sert plus à rien.
Pour éclairer un peu la différence type / classe, une variable a un type (en Java, C++...), et un objet a une classe et des types.
Oui. P.ex. si je propose une interface Coloré pour mes points et rectangles : se pose le problème de l'attribut couleur qui a de fortes chances de se retrouver dans toutes les classes promettant le service.
C'est parce que :
- soit il fallait prévoir dès le début qu'un objet géométrique pouvait avoir une couleur (pas deux classes : Point2D et Point2DColoré mais seulement ObjetGéoColoré et les autres qui en héritent) ;
- soit il faut utiliser un autre mécanisme, absent des primitives Java (mais que l'on peut simuler par délégation), les Mixin ou les Traits.
Oui. Le classique cas: classe A avec attribut a, classe B et C qui héritent de A et classe D qui hérite de B et C. L'attribut a est hérité deux fois par D. Comment gérer ça ? Qu'est-ce que cela peut bien signifier ?
Parfois, le programmeur voudrait deux a, parfois il n'en veut qu'un. C'est donc aussi un problème dans la tête du programmeur.
Des automatismes sont maintenant utilisés pour simplement noté qu'un attribut est en fait délégué et ses fonctions sont « proxysées » automatiquement.
C'est un peu le problème avec tous les exemples que l'on me sort pour dire que l'héritage multiple est plus utile que néfaste ;o)
Aucune et plein.
Une interface est une classe abstraite, donc c'est une classe, donc on en hérite.
Mais cela correspond à un héritage de comportement, pas de structure. (Voir plus haut type / classe...)
Oui, c'est une mauvaise conception : le modèle de calcul (= les classes qui servent à représenter tes données géométriques) doit être découplé du modèle de dessin (UI).
C'est le MVC.
Ok. Tu vas me dire que tu dois dupliquer encore ton arbre d'héritage mais c'est à toi de choisir :
- ou tu sépares proprement application et interface (c'est-à-dire que tu fais un modèle pour le calcul, un modèle-proxy pour donner à l'UI et une UI (avec ses objets à elle : widgets de toutes sortes)) ;
- ou tu ne fais qu'un modèle qui mélange à la fois les structures et les services pour le calcul et pour l'UI.
Tu admettras quand même que les concepts d'instance et de classe sont suffisamment distincts pour faire que, pour un même modèle, seulement un seul peut s'appliquer (c.-à-d. que tu n'as pas le choix entre l'un ou l'autre : il y en a un qui s'applique et l'autre qui ne veut rien dire).
Conceptuellement, il y a un problème dans le cas du diamant : que veut dire hériter de deux fois la même structure ?
Conceptuellement, l'héritage multiple englobe aussi les Mixin. (Ruby les différencie en utilisant des modules, j'aurais peut-être préféré un mot-clef mixin.)
Donc, je ne dis pas que ce n'est pas correct, mais, comme on est parfois obligé lorsque l'on enseigne des concepts complexes, on exagère un peu les mises en garde (parce que tout le monde se croit assez malin pour les transgresser) en en faisant des interdictions (puisque, de toute façon, on peut s'en passer).
Donc, comme la plupart des problèmes de l'héritage multiple (tous ?) se posent pour l'héritage de structure multiple, une solution pour les éviter est de l'empêcher. Par contre, l'héritage multiple de services ne pose pas de problème (si deux services ont le même nom, ils doivent représenter la même chose, sinon il y a un problème de nommage dans le modèle).
Je pense en fait que l'on est en train d'arriver à des concepts plus précis.
Au départ, il n'y a que l'objet, tout est objet, blabla... Mais on s'est vite rendu compte qu'il y avait plein de concepts différents et on a pas encore fini de les différencier correctement. On différencie maintenant héritage de structure et de services, on parle d'aspects, de mixins... Il faut encore poser tout ça pour que ça ressemble à quelque chose.
1. Le GC de Java fonctionne aussi avec compteur de références. Je pense que tu voulais plutôt dire que le nettoyage est, dans un cas, seulement fait lorsqu'il y a besoin de place, et dans l'autre cas, dès que la référence arrive à zéro.
2. Pour les histoires de propreté avec les E/S etc., il est à mon avis bien plus propre de le faire explicitement (et même dans le finally d'un try pour être bien sûr que c'est fait).
[^] # Re: Mes deux centimes ...
Posté par Sylvain Sauvage . En réponse au journal Repenser les langages et le développement logiciel. Évalué à 5.
[^] # Re: Mes deux centimes ...
Posté par Sylvain Sauvage . En réponse au journal Repenser les langages et le développement logiciel. Évalué à 6.
Java a été conçu après 20 ans d'expériences en POO, après que l'on a pu conceptualiser pas mal de zones d'ombre. Et, à ce moment, l'on s'était rendu compte que l'héritage multiple posait beaucoup de problèmes et qu'il fallait faire une différence entre l'héritage de structure (classes) et l'héritage de comportements (interfaces). On s'est aussi rendu compte que la majorité des problèmes de l'héritage multiple sont dus à l'héritage multiple de structures (problèmes de l'héritage en diamant, p.ex.). On s'est aussi rendu compte que les autres cas d'héritage multiple sont relativement rares (comparativement aux ennuis) et facilement contournables par délégation.
Maintenant, on s'apperçoit qu'il y a d'autres problèmes en POO, comme les aspects p.ex.
Pour en revenir à ton exemple précis (que j'ai eu du mal à obtenir hier, d'où une réponse seulement aujourd'hui), tu fais plusieurs choix discutables, p.ex. que Laguna est une classe et que Renaut est une classe. Voiture est bien une classe, mais Renault est une instance de la classe Constructeur et Laguna une instance de la classe Modèle. Voiture aura donc deux attributs : constructeur et modèle.
Alors tu me répondras : c'est de la délégation, c'est plus joli avec de l'héritage. Mais l'héritage n'a rien à voir dans ces relations. Le fait que tu puisses remplacer de l'utilisation (composition/aggrégation) par de l'héritage et que cela soit plus court à écrire n'est pas une raison pour le faire. Conceptuellement, ça ne tient pas.
[^] # Re: J'ai rien compris :(
Posté par Sylvain Sauvage . En réponse à la dépêche Le point sur le traitement graphique sous Linux. Évalué à 2.
1. avoir un pilote libre fourni par le constructeur ;
2. avoir les spécs pour pouvoir faire un pilote ;
et, au pire, certains s'accomoderaient plus ou moins temporairement,
3. avoir un pilote fourni par le constructeur.
Avoir les spécs, ou plutôt l'API, est une conséquence du 1 (si on a un pilote libre, pas trop crypté, on peut l'étudier et le modifier si besoin¹).
Et il n'y a pas trop de raisons que le constructeur ne fournisse pas de pilote pour son matériel à lui qu'il a développé lui-même.
¹ : si le pilote constructeur fonctionne, on n'a pas forcément _besoin_ de le modifier (ok, un hacker le fait parce qu'il peut le faire, mais l'histoire de RMS, c'était parce que le programme de son imprimante était pourrave).
[^] # Re: syslogd
Posté par Sylvain Sauvage . En réponse au message Accès concurrents, deception windowsienne. Évalué à 3.
Mais, après, faudra pas s'étonner d'avoir mal au cul...
[^] # Re: c'est tjs le même problème...
Posté par Sylvain Sauvage . En réponse à la dépêche La version 3 de Nessus sera propriétaire. Évalué à 2.
Ça n'est vrai qu'en théorie. L'« ascenseur social » est bloqué. Les enfants d'ouvriers¹ ont quand même beaucoup plus de mal. (Et je ne parle pas des personnes issues de l'immigration.)
¹ : je prends ce terme pour simplifier
# gagner des brouzoufs
Posté par Sylvain Sauvage . En réponse à la dépêche La version 3 de Nessus sera propriétaire. Évalué à 4.
On peut donc très bien faire payer le logiciel et de ne distribuer le source qu'à ses clients payants. Le seul moyen de perdre cette source de brouzoufs est que l'un des clients utilise son droit à redistribuer le logiciel (et ses sources) pour moins cher (voire gratuitement).
Or, il existe peu de logiciels qu'un client prendra la peine de redistribuer. Il existe aussi peu de clients qui le feront. Il faut mesurer le bénéfice que le client a à redistribuer.
Il s'agit juste de savoir choisir ses clients.
[^] # Re: c'est tjs le même problème...
Posté par Sylvain Sauvage . En réponse à la dépêche La version 3 de Nessus sera propriétaire. Évalué à 1.
[^] # Re: Pour continuer le débat
Posté par Sylvain Sauvage . En réponse au journal Python on rails. Évalué à 3.
Katz ne compare pas RoR avec Zope, ni les bibliothèques de Ruby avec celles de Python.
Il explique simplement que le principe exposé par Graham de bottom-up design (ci-après BUD) est en fait un des principes de Ruby et de Lisp.
RoR est une sorte de « Ruby++ pour le web ».
Il dit aussi que c'est pour cela que RoR est bien : c'est du Ruby et, en même temps, c'est plus que du Ruby.
Il donne Zope 2 comme contre-exemple : c'est en Python mais ce n'est pas du Python. Il pense que c'est pour cela que Zope a eu des problèmes et que Zope X3 a été lancé.
Voilà. La réponse à la question posée dans le titre (Est-ce que RoR aurait pu être écrit sans Ruby ?) est non, car pas de BUD, pas de RoR et Ruby permet le BUD et oui, car il n'est pas le seul (mais c'est quand même 'achetement pratique en Ruby ;o).
[^] # Re: En bash
Posté par Sylvain Sauvage . En réponse au message BDD sous SQLITE. Évalué à 2.
Sinon,
awk "BEGIN {FS=\";\"} { printf \"INSERT INTO table (c1, c2...) VALUES ('%s', '%s'...);\n", \$1, \$2} ' monfichier | sqlite mabase
marche aussi.
(Étant donné qu'on connaît déjà forcément le nombre de champs (colonne1...), on est pas obligé de jouer avec sed pour ajouter les ' ' autour des valeurs.)
[^] # Re: Dans certaines entreprises
Posté par Sylvain Sauvage . En réponse au journal Le comble du development en code fermé?. Évalué à 6.
Si la documentation du langage a aussi été conservée mais que l'on a plus de compilateur, il ne sera sûrement même pas nécessaire de refaire un compilateur mais seulement un traducteur.
Le SE et la « machine compatible » ne sont pas non plus indispensables avec un traducteur/interprète/machine virtuelle que l'on peut concevoir à partir de la doc du langage.
Avec un binaire, ben il faut un émulateur _qui existe_ ou, pire, un décompileur (ce qui donnera un code imbitable et très difficile à modifier/reprendre).
# shell
Posté par Sylvain Sauvage . En réponse au message BDD sous SQLITE. Évalué à 2.
Voir aussi NoSQL : http://www.linux.it/~carlos/nosql/current-doc/NoSQL.html(...)