Keresés
Hírlevél
 
Kiemelt témák
»Hogyan védjem meg a portálomat?
»Google wave
»Assembly :: röviden
Állás/munka
»Profi PHP szakit sörért felbérelnék :)
»IPhone App elkészítése
»Profi sitebuildert keresünk projekt alapon
»IT projektkoordinátort keresek Tatabányára
»Másodállást keresek, C# és C++
» több téma
Tudástár
?Link szövegének értékátadása fájlba
?Szövegszerkesztő c#
?Termékkereső típusra, gyártóra, kategóriára
?PHP mappa méretének meghatározása+ kiterjesztés
?TGridPanel - adott rész színének megváltoztatása.
?Listbox elem színezése
?Rajzolás Canvas-re JAVA-ban
?Statikus adattag
Ajax ellenőrzés, eredményfüggő megjelenítés
?Kép megjelenítési probléma
?C#-ban txt-ből másolás és írás
?Word szövegdoboz adatainak kimásolása
?C# 8 bites szabványos HEX file beolvasása
?C# kép betöltése futásidőben
?Free pascal unicode stringek
» több téma
Társalgó
»Melyik főiskola vagy egyetem?
»Trial megvalositasa
»PHP fejlesztés felsőfokon eladó !
»Eclipse 3.5.2 és Visual Editor 1.4
»C#-ban txt-ből másolás
»Adatvédelmi nyilvántartás
»Oracle SQL*PLUS windows kliens
»Weblap véleményezés
»HTML szerkesztő
»Webcam -> Flash -> Socket server
» több téma
ASP  |  C#  |  C++  |  CSS  |  Delphi  |  Flash  |  HTML  |  Java  |  JavaScript  |  Pascal  |  Perl  |  PHP  |  Python  |  Visual Basic  |  Visual C++  |    »    

Társalgó

»

Fejlesztőeszközök

»

Melyik programozási nyelv ér a legtöbbet?

»

Melyik programozási nyelv ér a legtöbbet?

nyitotta: Sami_hun, idő: 2010.01.22., moderátor: Ivn
  Értesítés változás esetén Felvétel kedvencekhez Küldés emailben Nyomtatható verzió
Ez a téma lezárásra került a moderátor által. A lezárás oka: Offtopic.
Sorrend:
Időzóna:
Blokkméret:
Sziasztok!

Arra lennék kíváncsi, hogy szerintetek melyek azok a programnyelvek, amelyek elsajátításával a legtöbb pénzt lehet keresni a többihez képest. Az is érdekel, hogy melyik a legkeresettebb és az is, hogy melyiket fizetik meg a legjobban.
Hali!

Off-topic alert!

Ezt csak futásidőbe fogod tudni eldönteni, pl. az "is" operátorral. Egyébként az aspektus orientált programozási infrastruktúrával kivitelezhető lenne egyszerűbben: Delphi Prism - AOP for .NET 4.0. Kódot leírni kóddal. Ez nagyon ott van nekem, a Világ egyik legjobb ötlete volt beletenni a nyelvbe, kismillió monoton feladattól megkímélhet. előzmény
Ebben teljesen igazad van.

"Nem vagy ezt, vagy azt... "
Na én pedig pont azt szeretném, hogy felsorolok típusokat és csak azokkal a típusokkal menjen.

Attól tartok, hogy ez a dolog messzebbre visz mint gondoltam...
:(
előzmény
Másrészt, interfészt többet is megalósíthat egy osztály. Ezzel a megszorítással: class Class1<T> where T: IV4, IV3C te kiköveteled a fordítótól, hogy mindkét interfész legyen implementálva a T típus által. Nem vagy ezt, vagy azt... előzmény
Konkrét tipizálás után már nem lenne gond ezzel valóban, mivel az egyértelmű lenne, viszont az osztályon belül nem egyértelmű. Pl.:

class Class1 { public void Method1() { } }   
class Class2 { public void Method2() { } }

class MyClass<T> where T : Class1, Class2
{
    private T field;

    void DoIt()
    {
        field.Method1();
        field.Method2();
    }
}

Ilyenkor a compilernek ki kellene gyomlálni a konkrét tipizálás után azokat a metódushívásokat, amik azon az osztály típuson értelmezhetetlenek. Interfész esetben más, mert ott megnézed, hogy megvalósítja az osztály a felület, avagy sem. Ha igen, akkor 100%, hogy a metódusait is. előzmény
Így viszont kétértelműség lenne:

class Class1 { public void Method1() { } }   
class Class2 { public void Method1() { } }
class MyClass<T> where T : Class1, Class2
{
    void DoSomething()
    {
        T obj = Activator.CreateInstance<T>();
        obj.Method1(); // De most melyiket???? Class1 v. Class2?                       
    }
}

A generikus osztályon belül még nem történik meg a konkrét tipizálás, máskülönben minek kellenek megszorítások a generikusokra? előzmény
Én speciel erre gondoltam:

class Class1 { public void Method1() { } }   
class Class2 { public void Method2() { } }
class MyClass<T> where T : Class1
{
   void DoSomething()
   {
      T obj = Activator.CreateInstance<T>();
      obj.Method1();                       
   }
}

Ez így most megy, meghívható egy T típusú objektumon a Method1(), mert a megszorításból tudja a fordító, hogy azok a metódusok biztos léteznek a típuson.
előzmény

".[itt is a compiler megpróbálja a megszorítások alapján felkíválni a megfelelő tagokat, de most nem tudja, hogy T az melyik a 3 közül]
"

checktiz:

    interface IV4
    {
        float x { get; }
        float y { get; }
        float z { get; }
        float w { get; }
    }
    interface IV3C
    {
        float x { get; }
        float y { get; }
        float z { get; }
        System.Drawing.Color Color { get; }
    }

    class Class1<T> where T: IV4,IV3C
    {
        void Test()
        {
            T x=default(T);
            float w =  x.w;
            System.Drawing.Color C = x.Color;

        }
    }
előzmény
"var newInstance = T(Activator.CreateInstance(typeof(T)); // nem tudja, hogy T micsoda"
Ez a kijelentés szerintem nem igaz, ugyanis a konkretizálás során egyértelműen eldől, hogy melyik típussal dolgozik.

A kérdésem igazából arra vonatkozik, hogy miért van lekorlátozva interface-re a megszorítás. előzmény
Ha például a sima class megszorítást használod, az is egy System.Object class megszorításnak felel meg tulajdonképpen. előzmény
Vagy egy közös interfészt használsz, vagy egy közös bázisosztályt megszorításnak. Típus-megszorítás csak interfész, vagy egy nem sealed osztály lehet. Továbbá a probléma ott van ezzel, amikor a compiler megpróbál a megszorítás alapján tipizálni. Például lesz egy ilyen metódusod, ahol felhasználod a T-t:

class Vertices<T> where T : Vector2, Vector3, Vector4
{
  public T CreateNew()
  {
     var newInstance = T(Activator.CreateInstance(typeof(T)); // nem tudja, hogy T micsoda
     newInstance.[itt is a compiler megpróbálja a megszorítások alapján felkíválni a megfelelő tagokat, de most nem tudja, hogy T az melyik a 3 közül]
  }
}

Ugyanígy a default(T) se lenne egyértelmű ebből a megszorításból.
előzmény
Lehet, hogy rosszul fejeztem ki magam.

Erre gondoltam:

using Microsoft.DirectX;

class Vertices<T> where T : Vector2, Vector3, Vector4
{

}

Ilyet miért nem lehet? előzmény
Drugs are bad, m'kay? előzmény
Na mindegy, most leakadok a témáról, már vagy 2 hónapja nem vagyok ráhangolódva a .NET-re amúgy se. Amíg nem lesz .NET 4.0 RTM, addig nem is érdekel különösképpen. előzmény
Okés, nem azért mondtam, csak próbáltam valami értelmet keresni abban, amit most zűrzavarnak, félrevezetésnek titulálunk. Jelen esetben most pont nem a boxolásos témára affektáltam, hanem a három típus létezik a C#-ban magyarázatra. Függetlenül ettől a véleményem továbbra is az, hogy a boxolásos téma nem a C# nyelvi specifikációban, illetve oldalán kellene megjelenjen csak, mert a boxolás, mint fícsör nem nyelvi, hanem CLI szabványokat követni próbáló Microsoft CLR megvalósítás. Ergo csak részint lehet köze ahhoz, hogy most C#, VB.NET, F#, Delphi Prism, vagy bármi mást használsz. előzmény
list.OfType<MyStruct>(); előzmény
from item in list
where item is MyStruct
select (MyStruct)item;
előzmény
Figyi, amiről én itt írtam, az nem filozófia, hanem a C# Team oldalán közölt információ. A keveredés az MSDN doksikban és magában a specifikációban abból adódik, hogy a CLI megfogalmazásai és szabályai nem ugyanazok, mint a C# nyelv hasonló kitételei. Pl az MSDN doksiban nem változik a magyarázat szövege, ha programozási nyelvet váltasz, csak a példák. Így nem írják oda a finomságokat, amúgy is szőrszálhasogatások ezek. Azt kell tudni, hogy mikor van implicit boxolás, mert kihat a kód teljesítményére.

Ha pl. egy adott funkciót egy felület jelöl, és szükségünk van egy azt megvalósító osztályra vagy struktúrára, akkor tudni kell, hogy ha struktúrával valósítjuk meg, akkor boxolni fog a rendszer, így nem hogy teljesítményt nyerünk az egyszerű struktúra implementációval, hanem vesztünk a doboz létrehozása és körbeudvarlása miatt.

Reflektorozz rá pl a Dictionary megvalósítására. Nézd meg az IEnumerable megvalósítást. Beteg. Egy in-class Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IDictionaryEnumerator, IEnumerator struktúra valósítja meg a logikát. Tehát, ha Dictionary.GetEnumerator() hívás van, akkor ebből kapsz vissza egy példányt. Viszont ezt kívülről IEnumerator<KeyValuePair<TKey, TValue>> - ként látod és kezeled, szóval a struktúra metódusból való kilépésekor boxol, és onnantól referenciaként kezeli a rendszer. Itt teljesítményvesztés van ahhoz képest, mintha a Ditcionary Enumerator egy sealed class lenne, mert ott nem kéne boxolni, és a boxon keresztül hívni az IEnumerator megvalósítást.

Ebből az a tanulság, hogy a framework írói sem voltak teljesen tisztában azzal, hogy ki-kivel van, amikor létrehozták. előzmény
Miért nincs olyan okosság a fordítóban, hogy konkrét struktúrákat is elfogadjon a "where" záradékban?
Még jó, hogy ilyen egyértelmű itt minden. De ha már itt tartunk, az MSDN például úgy fogalmaz, hogy 2 fajta típus van valóban, érték és referencia típus. Viszont alul ott a másik szöveg is, hogy unsafe kontextusban létezik a pointer fogalma is, mint önálló típus. Na most ha abból indulunk ki, hogy a .NET menedzselt és típusbiztos kód, akkor az első állítás, miszerint két típus létezik helytálló. Annál is inkább, mert pl. a VB.NET-be sincs unsafe kód. Persze ez megint olyan dolog, hogy honnan nézzük, de gondolom a szakirodalom abból indul ki, hogy minden kód ellenőrizhető (verifikálható), biztonságos kód, mintahogy az MSDN is. Ha a két nagy csoportot együtt vesszük és így a C#-ot egészben, akkor valóban 3 típus létezik. De abban az esetben helytáll a megfogalmaz, ha felső megszorítások definiáltak az állításban. Ha már filizofálgatunk... előzmény
Indirekt származik a System.ValueType-ból. Ez nem ugyanaz, mint ahogy a referencia típusok származnak egymásból és az object-ből! Ha ezt írod:

var vt = (System.ValueType)myStruct;

Akkor az megy, hiszen minden struktúra ValueType konverzibilis. WFT konverzibilis? Az, hogy a fenti sor, boxol mint a gép!

A spec. néha tényleg ellentmond magának. Amit idéztél az pontos megfogalmazás, csak nem teljes. Amit én idéztem egyel arrébról, az ugyanezt a részt tárgyalja, de ott pontos a megfogalmazás (csak nehéz megérteni). A C# FAQ-n meg ott a magyarázata ennek a struktúra dolognak valahol, én is onnan fogtam fel.

A legegyszerűbb módja megérteni az, hogy az object ős az ugyanaz, mint amikor megvalósít a struktúra egy felületet. Ha felírunk egy struktúrát felületként (és beletesszük pl egy List<IAkarmi>-be), akkor a struktúra -> felület konverzió boxolni fog! Máshogy nem is lehet.

Vita? Ki vitatkozik? Én csak mondom, ami van. Viszont az igaz, hogy ez annyira kicsi, sehová nem számító logikai része a nyelvnek, hogy elég csak annyit megjegyezni belőle, hogy a struktúra -> felület casting az boxol. Gyakorlati jelentősége ennek van, a többi okosságot úgyis megeszi a fordító, az általános object boxolási szabályokat meg mindenki ismeri. előzmény
Nem poénból mondom, hogy a származik szónak itt nincs teljesen definiálva a jelentése.

Nézzük csak ezt a C# language specből:

"All value types implicitly inherit from the class System.ValueType, which, in turn, inherits from class object. It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (§10.1.1.2).
Note that System.ValueType is not itself a value-type. Rather, it is a class-type from which all value-types are automatically derived."

Szóval minden Value Type egy System.ValueType nevű reference type-ból öröklődik (ami meg az Object-ből), igaz impliciten. Mit jelent az, hogy impliciten? Egyáltalán pontosan mit jelent, hogy származik? Komolyan kérdezem, mert több mindent is jelenthet. Most akkor a 'származik' reláció tranzitív egyáltalán? Ha nem, az nagyon szoktatlan értelmezése a 'származik' relációnak. Szvsz. nem túl precíz a spec., de végülis nem is kell túl precíznek lennie addig, amíg ahogy mondtam, azonos C# kódot nem lehet szemantikailag 2 félképpen értelmezni. (szemantikai különbség: "mást ír ki")

Illetve mi zárja ki azt, hogy ha valami valamiből származik, akkor ott legyen boxing?

Szvsz. a gyakorlatban egyszerűen arról van szó, hogy a value type-ok is az Object-ből származnak, hiszen az 'is' operátor true-t ad rá, meghívhatod rajta az Object függvényeit, stb.. Egyszerűen csak bizonyos szituációkban boxing zajlik le a háttérben, de ez az öröklődésnek nem mond ellent. Az meg logikus, hogy mikor zajlik le boxing: amikor muszáj neki. előzmény
akkor igen is fontos hogy egy egyszerű optimalizálási feladatnál 1000+ változó esetében van-e boxing vagy nem.

Az, hogy a fordító hogyan optimalizálja ki a dolgot, megint egy másik kérdés. Annak természetesen van értelme, hogy tudjad, hogy mi mennyi idő alatt fut le. Ehhez azonban nincs benne elég infó a Language spec-ben, és nem is teljesen feladata a language spec-nek ezt előírni. Ehhez az adott fordítót, illetve CLR megvalósítást kell ismerned.

Abban a kérdésben, hogy a int.ToString() mennyi idő alatt fut le, nincs semmi jelentősége annak a filozófiai kérdésnek, hogy ha az int a System.ValueType-ból származik, a System.ValueType meg a Objectből, akkor most valójában az int is az Objectből származik-e?
Ott csak a compiler, illetve CLR megvalósításnak és az abban lévő optimalizációknak van szerepe. előzmény
Szerintem ennek a vitának van értelme de csak egy igencsak specifikus rétegben: ott, ahol minden bit számíthat ha rossz helyre megy.

Tehát pl. ha egy iktatószoftvert kell írnom gyakorlatilag teszek rá hogy autobox fut-e le a háttérben vagy egyszerűen csak értékmásolás.
Viszont ha egy lingo vetélytársat készítek ahol ott múlik mondjuk a plusz 1000 USD ár, hogy az adott számítást milyen gyorsan hajtja végre a programom akkor igen is fontos hogy egy egyszerű optimalizálási feladatnál 1000+ változó esetében van-e boxing vagy nem.

De szerintem aki tipikus üzleti alkalmazásokkal foglalkozik annak max elég átolvasni és nagyjából tisztában lenni ezekkel hogy ha valamikor felmerülne ne csak üljön és azt kérdezze hogy mi a különbség a referencia és az érték típus között de igazából ennyire részletesen nem kell tudnia hogy a háttérben mondjuk egy adott műveletnél éppen egy értékadásnál van-e boxing.


Morzel előzmény
Én Java-s vagyok, de engedjétek meg, hogy beleszóljak, pláne, hogy belenéztem a C# language spec idevonatkozó részébe.

Egy nyelvről való olyan mélységű viták során, amikor már a language reference sem tűnik eléggé precíznek, van egy jó ökölszabály:

Járjunk el úgy, mint a matematikusok, amikor axiomatizálnak: semminek nem tulajdonítanak a. priori jelentést, hanem mondanak axiómákat, majd pedig formális állításokról azt mondják, hogy igazak, vagy nem igazak.

Ilyen szinten már nincs értelme azon vitatkozni, hogy a value type-ok "valójában" Object sármazékok-e vagy sem. Ez olyan, mintha azon vitatkoznánk, hogy a prímszámok pirosak-e? Mi a pontos jelentése annak, hogy egy szám piros? Mi a pontos jelentése annak, hogy valami valamiből származik?

Aminek van értelme:

A vita egyik résztvevője ad egy C# kódot, és azt mondja, hogy ennek szerinte azt kell kiírnia, hogy 'XYZ'.
A vita másik szereplője azt állítja, hogy ennek azt kell kiírnia, hogy 'ABC'.

Ekkor ez értelmes vita.

Ha nincs ilyen vízválasztó kód, vagyis mindkettőtök értlemezése szerint minden kód pontosan ugyanazt írja ki, akkor nincs értelme a vitának. Akkor azon vitatkoztok, hogy a prímszámok pirosak, vagy kékek. Ez már nem matematika, nem programozás, maximum filozófia.
Köszönöm a magyarázatot mindkettőtöknek, próbálom befogadni.

Nem tudom, mennyire vagytok toleránsak az offolással itt, bocs hogy nem az eredeti témában írok, azért az még érdekelne, hogy akkor mire való a System.ValueType? Object browserben megnéztem, van ilyen, azt írja: "Provides the base class for value types."
Ez tehát csak a boxing eljárás során object-té konvertált értéktípusok ősosztálya lenne? Magyarul a boxing például egy intet System.ValueType-pá konvertál? előzmény
Szerintem meg nem olvastátok se ti, se ezen blogok írói, se az MSDN doksi írói soha életükben a C# Language Spec. doksit. Right? Van rá egy láda söröm.

Akkor adhatod a láda sört, mert valamikor réges régen olvastam, csak más kérdés, hogy mennyi maradt meg belőle. Már ott tartok, hogy annak is örülök, ha arra emlékszek, hogy tegnap mi történt velem. Azért megnéztem most a Jeffrey Richter féle "CLR via C#" könyvet, abba is összekeverednek a dolgok:

If you look more closely at the documentation, you'll notice that all of the structures are immediately derived from the System.ValueType abstract type. System.ValueType is itself immediately derived from the System.Object type. By definition, all value types must be derived from System.ValueType.

Másrészt, ez nem csupán nyelv specifikus dolog, így ennek nemcsak a C# nyelvi specifikációban kellene szerepelnie.
előzmény
Ez az MSDN szöveg is hibás. Pontosabban az eleje ellentmonda a végének, ami pedig benne van a C# lang spec.-ben.

Erre már rá jöttem én is utána. Csak az MSDN iromány kavarta össze a dolgokat.

Magyarul a value típus konvertálódik object-té (boxing) és így kezelhető object-ként.

Ez eddig is világos volt. Ezért nem is tudtam hova tenni ezt a fícsört. Nem illik bele abba a gondolatmenetbe, hogy minden Object származék.

Másrészt erről nem az emberek tehetnek. Ha már saját maguk is össze-vissza, félreértelmezhetően írnak mindent, mit várjon az ember. előzmény
Na, még egy-két mondat off-ot, ha megengedtek!

A félreértések, miszerint mindenki az object típusból (direkt) származik, az ECMA-hoz leadott lang. spec. szövegéből jön. A "hivatalos", Heijlsbergék féle C# Lang. Spec. (itt van) a következőket tartalmazza:

C#'s type system is unified such that a value of any type can be treated as an object. Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type object. Values of value types are treated as objects by performing boxing and unboxing operations (§4.3).

Ahogy én is írtam, teljesen korrekten. Az object ős értéktípusoknál nem öröklési viszony (direct derived), hanem kezelési, vagyis konverzibilitási viszony (indirect derived). Logikailag, ha meghívunk egy int.ToString() metódust, akkor ott az int boxol objectté, és a boxon (ami már object) hívódik meg a ToString(), ami meghívja az int ToString() metódust, ami logikailag még csak nem is override! Persze az implementáció nem megy végig ezen a folyamaton, egyszerűen meghívódik a ToString(), a fordító ismeri az összes object metódust, így tudja ezt optimalizálni. De a logikája ez!

Az ECMA 334-es doksi pedig ezt írja (hibásan, hiányosan):

C# provides a "unified type system". All types-including value types-derive from the type object. It is
possible to call object methods on any value, even values of "primitive" types such as int.


Ezt javítják remélhetőleg.

Mindkét spec-ben közös hiba, hogy a mutató típus viszont semmiféle viszonyban nincs az objecttel, emiatt ez a fennti megfogalmazás nem teljes, oda kell, oda fogják írni, hogy: except pointer types.

SZERK.: Persze a Pointer Types részben ezt leírják, de az elejéről lemaradt:

Pointer types are a separate category of types. Unlike reference types and value types, pointer types do not inherit from object and no conversions exist between pointer types and object. In particular, boxing and unboxing (§4.3) are not supported for pointers. However, conversions are permitted between different pointer types and between pointer types and the integral types. This is described in §18.4.

Bocs az offért, de nem én néztem be, tényleg így van a regula.
Csak azért kérdezem, mert neked azért jobban hiszek, de mindenesetre furcsa, hogy a könyvek többsége félretájékoztatna?

Az általam kézben tartott .NET könyvek jelentős hányada azzal kezdi, hogy a CLR egy virtuális gép, ugyanúgy, mint a Java JVM. Még a Wiki-n is ez van, ha azóta ki nem javították.

Plusz ez a value típus származik-e vagy csak konvertálható-e objectté hetvenedrangú hiba ahhoz képest, hogy a szakkönyvek és blogok konzisztensen megfeledkeznek a C# 3. nagy alapvető típuscsoportjáról: a mutatókról. A lang. spec. egy egész fejezete foglalkozik a tulajdonságaival, nagyon nagy, fontos, és különálló nyelvi típuskészletről van szó. Szarvashiba megfeledkezni róla.

Ez idővel csak bonyolódik. Bevezették a LINQ-et, természetesen egyből mindenki nagyon-nagyon elkezdett hozzá érteni (se). Aztán ennek az az eredménye, hogy akár nagy tiszteletnek örvendő szakmai bloggerek, önjelölt tanítómesterek tollából is árad az ökörség tonnaszám. Legutóbb Sándor barátom blogjában hívtam fel a figyelmet egy ilyen esetre. (A kommenteket nézzétek, alulról kezdve.)

Hogy van az a mondás? Aki ért hozzá, az csinálja, aki meg nem, az tanítja. Ez van. előzmény
Ez a téma lezárásra került a moderátor által. A lezárás oka: Offtopic.
Belépés
E-mail cím:
Jelszó:

RSS források
-Hírek
-Cikkek
-Fórumok
Top pontgyűjtők
»Micu1.800
»Árnyék910
»vinie530
»Frostech0440
»Riha420
»djjjozsi410
»pelz350
»stl340
»klorand320
»NevemTeve230
Hírek
»Cassandra-ra tér át a MySQL-ről a Digg is
»Letölthető a Mozilla Jetpack SDK első kiadása
»Saját alkalmazásboltot nyitott a Google
»Súlyos sebezhetőség minden Apache kiszolgálóban
»Natív 3D-s támogatás a legújabb Android fejlesztőkészletben
» több hír
PC Fórum hírek
»Lopta a Firefox Jetpack terveit a Mozilla ?
»Minden weboldalra beköltözne a Facebook
»Nem boldogul az legújabb merevlemezekkel az XP és a Linux
»Átírják a Firefox licencszerződését
»Több tízezer nebuló a Microsuliban
»Sebezhető az Internet Explorer és az Opera is
»Még márciusban megjelenik az Intel nyolcmagos szerverlapkája
»Hamis Core i7 processzorokat árultak a neten
Tagi blogok
»USB
»PHP, mint sablonmotor egyszerűen
»Én és linux
»Coming out