<FromGitter>
<Blacksmoke16> > also `initialize` is a special method used for initialization of state which is invoked by compiler generated `self.new` method ⏎ ⏎ as @naqvis said
<FromGitter>
<alexherbo2> @Blacksmoke16 so for methods in a module extended with `extend self`, what do you write in spec to refer them?
<FromGitter>
<Blacksmoke16> you'd have to use `.`
<FromGitter>
<Blacksmoke16> assuming the module is just being used as a namespace to store those methods
<FromGitter>
<Blacksmoke16> like if you're intending to use the methods like `TheModule.the_method` use `.`, but if you're intending on including the module in another type then you'd prob use `#the_method` as it would be in the context of an obj instance
<FromGitter>
<alexherbo2> the thing is an `extend self` can be both no?, we can directly call `TheModule.the_method` or `the_method` when `include TheModule`
<FromGitter>
<Blacksmoke16> yea, depends on what context you intend to use the method
<FromGitter>
<Blacksmoke16> prob doesnt really matter too much
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
andremedeiros has quit [Read error: Connection reset by peer]
andremedeiros has joined #crystal-lang
<FromGitter>
<RespiteSage> Is there a way to reserve capacity in an already-constructed `Array`? I'm not seeing any methods in the docs.
<FromGitter>
<Blacksmoke16> i.e. resize the array manualy?
<FromGitter>
<Blacksmoke16> doesnt look like it w/o creating another
<FromGitter>
<Blacksmoke16> could you give it an initial capacity when initializing it?
<FromGitter>
<RespiteSage> I can rearrange the code to do that, probably.
<FromGitter>
<elementio:salt-rock-lamp.ems.host> is there a clear explanation anywhere in the crystal docs of "<" vs "extends" vs "includes"? i don't have a ruby background so i don't know if this is considered common/basic knowledge in the ruby world.
<FromGitter>
<erdnaxeli:cervoi.se> "<" is classic object inheritance
<FromGitter>
<Blacksmoke16> `<` in inheritance akin to `extends` in some other languages, while `extends` and `includes` are composition, like traits in PHP
<FromGitter>
<elementio:salt-rock-lamp.ems.host> @Blacksmoke16 i'm not familiar with PHP's OO system either - can you elaborate?
<FromGitter>
<Blacksmoke16> what language are you coming from?
<FromGitter>
<elementio:salt-rock-lamp.ems.host> straight-shoota that was my question :) i should have been more open with "what i already know" instead of just asking. but i don't think either my self answer (just quoting the docs) or the other answer helped me understand the full thing. i will ask a separate question that i can either self-answer or hopefully someone else will answer.
<FromGitter>
<elementio:salt-rock-lamp.ems.host> @Blacksmoke16: among general-purpose languages that support OO, i am most experienced with python.
<FromGitter>
<erdnaxeli:cervoi.se> so extending a module makes class methods, while including it makes instance methods
<FromGitter>
<elementio:salt-rock-lamp.ems.host> oh, inclusion is also for modules?
<FromGitter>
<elementio:salt-rock-lamp.ems.host> i thought it was for classes
<FromGitter>
<erdnaxeli:cervoi.se> inclusion is only for module, I don't think you can includes a class
<FromGitter>
<erdnaxeli:cervoi.se> you inherites from a class using "<"
<FromGitter>
<erdnaxeli:cervoi.se> like in python
<FromGitter>
<erdnaxeli:cervoi.se> except in crystal there is not multi inheritance like in python
<FromGitter>
<elementio:salt-rock-lamp.ems.host> right, and i believe inheritance with `<` is also present in ruby?
<FromGitter>
<Blacksmoke16> modules are for composition AND namespacing. Modules can be included/extended into other types (classes, structs, or other modules)
<FromGitter>
<Blacksmoke16> yes
<FromGitter>
<erdnaxeli:cervoi.se> yep, those concepts (include, exclude, modules) come from ruby
<FromGitter>
<elementio:salt-rock-lamp.ems.host> aha. ok this makes more sense
<FromGitter>
<Blacksmoke16> modules are also the way you can define pseudo interfaces
<FromGitter>
<elementio:salt-rock-lamp.ems.host> i see, anything implementing that interface would include or extend the module that defines the interface
<FromGitter>
<erdnaxeli:cervoi.se> coming from python too, the namespacing think was one of the hardest thing to understand when doing crystal
<FromGitter>
<erdnaxeli:cervoi.se> while in python you would define a module (which is juste a file) or a package (which is a folder), there are no such think in crystal
<FromGitter>
<erdnaxeli:cervoi.se> instead you define a module for namespacing
<FromGitter>
<Blacksmoke16> you cant have abstract class methods in crystal (atm?), so mainly need them for instance based methods
<FromGitter>
<erdnaxeli:cervoi.se> and you can define all you function, classes, structs, other modules, inside this module
<FromGitter>
<elementio:salt-rock-lamp.ems.host> so *practically* what's the difference between a module and a class? a module cannot be instantiated, but a class can?
<FromGitter>
<erdnaxeli:cervoi.se> exactly
<FromGitter>
<elementio:salt-rock-lamp.ems.host> they both can have instance variables?
<FromGitter>
<Blacksmoke16> yes, but you wouldnt be able to use them w/o including it into another type
<FromGitter>
<Blacksmoke16> and fwiw a class/struct can also be used as a namespace
<FromGitter>
<erdnaxeli:cervoi.se> a module can only have class variable, with @@, which are global
<FromGitter>
<elementio:salt-rock-lamp.ems.host> and the difference between a class and struct is that the former is passed by reference and the latter by value (and as such can be stack allocated)?
<FromGitter>
<erdnaxeli:cervoi.se> yep
<FromGitter>
<elementio:salt-rock-lamp.ems.host> oh, modules dont have instance variables like `@x`? only class variables `@@x`?
<FromGitter>
<Blacksmoke16> > a module can only have class variable, with @@, which are global ⏎ ⏎ Pretty sure this isn't true, see https://play.crystal-lang.org/#/r/ay5p
<FromGitter>
<elementio:salt-rock-lamp.ems.host> if in a class i `include` a module that refers to `@@x` in the module, does that become a `@x` in the class?
<FromGitter>
<erdnaxeli:cervoi.se> yeah, it works if you include the module
<FromGitter>
<Blacksmoke16> a module on its own can only have class ones yes, but you can totally define ivars in a module to share them (and additional methods) in various other types
<FromGitter>
<erdnaxeli:cervoi.se> I think I actually never used "extend"
<FromGitter>
<erdnaxeli:cervoi.se> in real code
<FromGitter>
<erdnaxeli:cervoi.se> so yeah, salt rock lamp, just use module for namespacing, interfaces with abstract methdo, or simple mixin patterns :D
<FromGitter>
<Blacksmoke16> yea i cant say i have either
<FromGitter>
<elementio:salt-rock-lamp.ems.host> makes sense, but i dont think i understand how the scoping and instance/class variable stuff works yet
<FromGitter>
<elementio:salt-rock-lamp.ems.host> what is `items`?
<FromGitter>
<Blacksmoke16> `self.items`, it assumes the including type has a method called `items`
<FromGitter>
<Daniel-Worrall> Meaningless until it is included
<FromGitter>
<elementio:salt-rock-lamp.ems.host> i see. and what if i define a top-level `items` function but don't define it in the include-ing class?
<FromGitter>
<Blacksmoke16> pretty sure it wouldnt work
<FromGitter>
<Daniel-Worrall> Crystal only compiles code that is run. Modules aren't compiled unless they are included and/or ran
<FromGitter>
<naqvis> > https://play.crystal-lang.org/#/r/ay5u why this does not work? ⏎ ⏎ I would say this should be a bug, class vars are included as well, but accessing them like this is treating them as re-definition
<FromGitter>
<Daniel-Worrall> Yeah, it just runs that code from the callsite. Top level would be ran when included without the definition in the include-ing class
<FromGitter>
<Blacksmoke16> oh, i suppose that makes sense
<FromGitter>
<erdnaxeli:cervoi.se> naqvis (Ali Naqvi): weird
<FromGitter>
<Daniel-Worrall> A way to avoid global definitions breaking intentions from inclusions would be to use `self.method` https://carc.in/#/r/ay6u
<FromGitter>
<elementio:salt-rock-lamp.ems.host> huh, that scoping with implicit `self` is kind of hairy
<FromGitter>
<elementio:salt-rock-lamp.ems.host> seems like a footgun waiting to happen if you aren't diligent about using `self`
<FromGitter>
<Daniel-Worrall> The solution would be don't polute your global scope :)
<FromGitter>
<erdnaxeli:cervoi.se> most of the time I have only one class or module per file, without any thing at top level, so that's ok
<FromGitter>
<erdnaxeli:cervoi.se> and then, tests should catch it
<FromGitter>
<Daniel-Worrall> and you probably will run into a case where the method signatures are different
<FromGitter>
<Daniel-Worrall> Getting into the habit of typing your parameters and returns helps
<FromGitter>
<naqvis> i use modules as interface and declaring abstract methods inside ensures you follow the signature when you include them
<FromGitter>
<elementio:salt-rock-lamp.ems.host> i get that the typical file structure might make it a non-issue in most cases, but i guess it just makes me squirm. ⏎ ⏎ for example, the (very minimal clone of) api for a popular http client in python: ⏎ ⏎ ```code paste, see link``` ... [https://gitter.im/crystal-lang/crystal?at=60804ea0b6a4714a29db1d68]
<FromGitter>
<Blacksmoke16> im sure its a real problem, but in practice it's mitigated by how Crystal structures its code
<FromGitter>
<elementio:salt-rock-lamp.ems.host> or worse, consider the opposite situation: where you define a module that refers to something that should be an instance method, but the user never implements that method, and instead there (by accident or by design) is a top-level function of the sam ename
<FromGitter>
<Blacksmoke16> how you should structure your code*
<FromGitter>
<Blacksmoke16> defining top level methods like that is a smell anyway
<FromGitter>
<elementio:salt-rock-lamp.ems.host> as opposed to inside a module?
<FromGitter>
<elementio:salt-rock-lamp.ems.host> i see, so there's no way to *directly* access an instance variable from outside the class, unlike e.g. python (which i know is a bit weird w. respect to its class/OO design)
<FromGitter>
<elementio:salt-rock-lamp.ems.host> hence the need for getter/setter/property
<FromGitter>
<Blacksmoke16> welllll there is but you shouldnt do it
<FromGitter>
<naqvis> you can do that, but please DON'T
<FromGitter>
<Blacksmoke16> and im not going to tell you how :P
<FromGitter>
<naqvis> Encapsulation need to be followed :P
<FromGitter>
<erdnaxeli:cervoi.se> the pattern is to use getter/setter/property
<FromGitter>
<erdnaxeli:cervoi.se> unlike python where everything is public
<FromGitter>
<Blacksmoke16> or define the getter/setter yourself if it needs custom logic
<FromGitter>
<erdnaxeli:cervoi.se> yes
<FromGitter>
<Daniel-Worrall> Crystal lets you shoot yourself in the foot, just like most languages, but we'll always encourage you not to
<FromGitter>
<elementio:salt-rock-lamp.ems.host> @Blacksmoke16: is the `::` in `MyHTTPClient::ClientSession` just part of the name? or is it something syntactically special?
<FromGitter>
<Blacksmoke16> it's used to separate the namespaces the type is actually located
<FromGitter>
<Blacksmoke16> i.e. the FQN
<FromGitter>
<Blacksmoke16> so its saying `ClientSession` exists in the `MyHTTPClient` type
<FromGitter>
<Blacksmoke16> like other langs namespacing allows you to have two types with the same name among other things
<FromGitter>
<Blacksmoke16> mainly to prevent conflicts, like if you're making a shard all your types should be in a like `MyApp` namespace
<FromGitter>
<elementio:salt-rock-lamp.ems.host> yeah i understand its purpose. i was wondering if it was some kind of syntax that the compiler recognized, or just a convention for developers to use
<FromGitter>
<elementio:salt-rock-lamp.ems.host> it looks like i can't name a top-level method `a::b` for example
<FromGitter>
<Blacksmoke16> right, it's just for types
<FromGitter>
<Blacksmoke16> although there is syntax like `::SomeType`
<FromGitter>
<Blacksmoke16> or `::my_method`
<FromGitter>
<elementio:salt-rock-lamp.ems.host> that bypasses looking within the current class/module and looks only in the surrounding scope. right?