ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
tommye2 has joined #crystal-lang
<tommye2> hi guys, how do I set a default value to hashes? this is my current code: https://carc.in/#/r/b0va
<FromGitter> <Blacksmoke16> https://carc.in/#/r/b0vf
<tommye2> thanks a bunch
<tommye2> <3
<tommye2> umm
<FromGitter> <Blacksmoke16> Hm?
<tommye2> im having trouble again, see this: https://carc.in/#/r/b0w0
<FromGitter> <Blacksmoke16> usually its not needed to type local vars like that
<FromGitter> <tenebrousedge> `Hash` isn't really what you want as a type restriction, probably
avane has quit [Ping timeout: 260 seconds]
<FromGitter> <Blacksmoke16> but the problem is you're saying each of those local vars can *only* be a String for example
<FromGitter> <Blacksmoke16> or *only* be an Int32
<FromGitter> <Blacksmoke16> but the value from the hash can be *either* a String or Int32
<tommye2> oh
<tommye2> what would you recommend for this ?
<FromGitter> <Blacksmoke16> whats the end goal? or the real use case you're working on?
<tommye2> i want to pass some options inside of the method arguments, i know i can use arguments just like that without hashes, but hashes give a object vibe, and it seems cleaner
<tommye2> the options can either be a string or int32 or booleans inside of the hash
<FromGitter> <Blacksmoke16> i.e. like `$options = []` like you'd do in PHP?
<FromGitter> <tenebrousedge> https://carc.in/#/r/b0w8
<FromGitter> <Blacksmoke16> are the options arbitrary? Or are they known ahead of time?
<tommye2> im not familiar with php, i did use to do it before, but i hardly remember it, if you worked with javascript before you should know what objects are, thats what im trying to achieve
<tommye2> `{message: "world", score: 5}`
<tommye2> but that what you just sent seems to work perfect, thank you !
<FromGitter> <Blacksmoke16> those are the only 2 options?
<FromGitter> <tenebrousedge> trying to emulate a loosely typed key value store is probably not the best
<tommye2> ummm
<tommye2> well not only two
<FromGitter> <Blacksmoke16> how many? more than 4? or?
<tommye2> the actual app/script will have 6 options inside of the "object"
<FromGitter> <tenebrousedge> records and enums are :plus1:
<FromGitter> <Blacksmoke16> any reason to not just make them arguments to the function?
<FromGitter> <Blacksmoke16> or yea, the more idiomatic approach would to not use a hash and use a record
<FromGitter> <Blacksmoke16> it seems silly to create a hash just to pass it to a function when you could pass the args directly
avane has joined #crystal-lang
<FromGitter> <tenebrousedge> JS is a great language, and the way it lets you glom objects together is super interesting. Trying to do the same thing in Crystal is just setting yourself up for fights with the type system. Note in the Hash, the value is forced into being `String | Int32 | Boolean`. Since those types have few methods in common, you're going to have to distinguish them pretty every time you try to call a method
<FromGitter> <Blacksmoke16> the pain you'd have felt at runtime in JS is now at build time; kinda like what TS does for JS
<tommye2> yeah I see
<tommye2> im not sure
<tommye2> you guys are better at this than me
<tommye2> hashes reminded me of js objects so i thought to use them
<FromGitter> <Blacksmoke16> you should mostly try to not use hashes, they're pretty bad
<FromGitter> <Blacksmoke16> at least like you would in Ruby, or js
<FromGitter> <tenebrousedge> or PHP
<tommye2> to sum up : what should i be using instead ?
<FromGitter> <tenebrousedge> `record` is a great tool
<FromGitter> <Blacksmoke16> if you're creating a hash just to pass the args, just pass the args directly
<FromGitter> <tenebrousedge> also that
<FromGitter> <Blacksmoke16> if thats not possible because you need a container to pass around, a record is prob your best bet
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/toplevel.html#record(name,*properties)-macro
<tommye2> I see.
<tommye2> thanks :)
<tommye2> this will work just fine.
<FromGitter> <riffraff169> completely arbitrary not really related to crystal but kind of question
<FromGitter> <riffraff169> what is the difference between carc.in and play.crystal-lang.org ?
<tommye2> theyre the same
<FromGitter> <riffraff169> ok, cool
<tommye2> i suppose one or other is just a reverse proxy
<FromGitter> <tenebrousedge> `crystal play` is cool too
<tommye2> yeah
<FromGitter> <riffraff169> ive done that when im just testing locally, but usually i just create the program and do `crystal run`
<tommye2> i use carc.in for quick browser stuff tbh
<tommye2> short domain
<FromGitter> <tenebrousedge> I tend to have `icr` open in a terminal for quick questions
<FromGitter> <tenebrousedge> and for annoying @Blacksmoke16 😉
<tommye2> what am i doing wrong now? https://carc.in/#/r/b0wi smh i keep messing up stuff
<tommye2> Ohhhh
<tommye2> the Random.rand needs ()
<tommye2> thanks for your help btw guys
<FromGitter> <tenebrousedge> 😎
aquijoule_ has joined #crystal-lang
richbridger has quit [Ping timeout: 265 seconds]
<FromGitter> <tenebrousedge> I need a safe way to go from `StaticArray[97, 98, 99, 0]` to `"abc"`
<FromGitter> <tenebrousedge> `String.new(array.to_unsafe)` is biting me
<FromGitter> <tenebrousedge> I can prooooooobably do `to_a`, maybe?
<FromGitter> <tenebrousedge> `join(&.chr).chomp('\0')` works
tommye2 has quit [Quit: Connection closed]
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <Blacksmoke16> hm
<FromGitter> <Blacksmoke16> is it actually `Int32`? or `UInt8`?
<FromGitter> <tenebrousedge> it's C chars, so UInt8
<FromGitter> <Blacksmoke16> so why doesnt `String.new arr.to_unsafe` work?
<FromGitter> <tenebrousedge> it does, my problem is something else
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <tenebrousedge> C function returning an unknowable number of bytes
<FromGitter> <Blacksmoke16> so?
<FromGitter> <Blacksmoke16> wait
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/b0xj
<FromGitter> <tenebrousedge> I have to pass C some vars to fill up. I've been using StaticArray for string data. This doesn't work with arbitrary length strings
<FromGitter> <Blacksmoke16> ah, was looking at the wrong overload
<FromGitter> <Blacksmoke16> cant just use a like `Pointer(UInt8)`?
<FromGitter> <Blacksmoke16> or `Pointer(LibC::Char)`
<FromGitter> <tenebrousedge> is C going to treat that like a `String` ?
<FromGitter> <Blacksmoke16> idt C has the concept of String types, so no
<FromGitter> <Blacksmoke16> the pointer needs to contain a nul byte at some point tho to denote the end of the string
<FromGitter> <tenebrousedge> C will do that for me
<FromGitter> <Blacksmoke16> then should be fine to just use `String.new ptr`
<FromGitter> <tenebrousedge> I'll see what happens
<FromGitter> <elementio:salt-rock-lamp.ems.host> how does that work with memory allocation?
<FromGitter> <elementio:salt-rock-lamp.ems.host> does the function allocate memory for itself? or are you expected to allocate a "big enough" buffer?
<FromGitter> <tenebrousedge> I allocate memory
<FromGitter> <elementio:salt-rock-lamp.ems.host> so if you allocate 100 bytes and the function only returns 50, the buffer could contain 50 bytes of junk after the `\0`, right?
<FromGitter> <tenebrousedge> or if I don't allocate enough, then there's no `\0` and things go pear shaped
<FromGitter> <Blacksmoke16> hence why this method is unsafe :P
<FromGitter> <elementio:salt-rock-lamp.ems.host> are you at least able to stop and allocate more memory if you see the buffer getting full?
* FromGitter * tenebrousedge ponders
<FromGitter> <elementio:salt-rock-lamp.ems.host> or is it extra-dangerous and you have to guess beforehand
<FromGitter> <tenebrousedge> most of the code is happening at compile time, so that the compiler can figure out what types it's getting from C without worrying the user unduly. I think that I can do string allocation at runtime though, since it won't affect the type of the returned value
chachasmooth has quit [Ping timeout: 276 seconds]
chachasmooth has joined #crystal-lang
chachasmooth has quit [Ping timeout: 252 seconds]
chachasmooth has joined #crystal-lang
<FromGitter> <elementio:salt-rock-lamp.ems.host> i believe that's how python allocates memory for its lists
<FromGitter> <elementio:salt-rock-lamp.ems.host> it allocates extra space in advance and allocates more memory in "chunks" when the interpreter needs to append to or extends the list
<FromGitter> <elementio:salt-rock-lamp.ems.host> rather, how cpython allocates memory; pypy probably does something totally different
<FromGitter> <tenebrousedge> that's too complex for this use case
<FromGitter> <tenebrousedge> I tend to doubt it's even possible
<FromGitter> <tenebrousedge> but I also can't create a StaticArray unless I know its size at compile time, and this is unknowable
<FromGitter> <elementio:salt-rock-lamp.ems.host> right
<FromGitter> <tenebrousedge> so I can't do what I want 😦
<FromGitter> <tenebrousedge> oh well
<FromGitter> <elementio:salt-rock-lamp.ems.host> not that you necessarily want to do it this way, but i think the idea is you'd keep a counter of the number of bytes received so far, and when you get close to filling the buffer you'd just allocate a bunch more memory. e.g. if you're reading a 100 bytes at a time from somewhere, when your buffer gets within 20 of its allocated size you stop reading and allocate 100 more bytes before
<FromGitter> ... continuing
<FromGitter> <tenebrousedge> the "filling" part here happens entirely in C
<FromGitter> <tenebrousedge> this boils down to, the end user specifies the size of the buffer they need or Bad Things Happen
<FromGitter> <Blacksmoke16> but doesnt it only consume until a nul byte?
<FromGitter> <Blacksmoke16> when creating the string, or are you talking about something else?
<FromGitter> <elementio:salt-rock-lamp.ems.host> well the problem is what happens if the string is 1000 bytes long, but you only allocate 600 bytes, so the last 400 bytes *and* the nul byte are lost
<FromGitter> <elementio:salt-rock-lamp.ems.host> (or your program segfaults trying to store them
<FromGitter> <elementio:salt-rock-lamp.ems.host> )
<FromGitter> <Blacksmoke16> but im pretty sure crystal allocates based on the size of the string when doing `String.new ptr`
<FromGitter> <tenebrousedge> yeah but I need to pass C a fixed-size structure, whose size is known at compile time
<FromGitter> <Blacksmoke16> what was the reason you cant use `LibC::Char*`?
<FromGitter> <tenebrousedge> it didn't work?
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <tenebrousedge> I mean I don't know how to make it work
<FromGitter> <Blacksmoke16> the crystal or c part?
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=608b7b47d261cc4d749b838a]
<FromGitter> <Blacksmoke16> hmm
r0bby has joined #crystal-lang
<FromGitter> <Blacksmoke16> yea idk
<FromGitter> <Blacksmoke16> i guess in this case you cant use `LibC::Char*` given you need to provide a pointer that has memory allocated for it
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/b0yj wonder how this works then. does the static array resize itself? 🤔
<FromGitter> <elementio:salt-rock-lamp.ems.host> why do you need the size to be known at compile time
<FromGitter> <tenebrousedge> so that the compiler knows what types are actually coming from C
<FromGitter> <tenebrousedge> that's pretty neat, @Blacksmoke16
<FromGitter> <tenebrousedge> `typeof(LibC::Char[1])` ⏎ => Array(UInt8)
<FromGitter> <tenebrousedge> how wonderful, that works like a charm
<FromGitter> <tenebrousedge> hmmm, no, I'm still using fixed buffers there
<FromGitter> <elementio:salt-rock-lamp.ems.host> oO how does that work
<FromGitter> <tenebrousedge> I have no idea tbh
<FromGitter> <elementio:salt-rock-lamp.ems.host> ```code paste, see link``` ⏎ ⏎ this is what that crystal code looks like to me, which does not work as intended [https://gitter.im/crystal-lang/crystal?at=608b8e5120d4f0263192a809]
<FromGitter> <elementio:salt-rock-lamp.ems.host> is some magic happening under the hood?
<FromGitter> <naqvis> that's not true, code in crystal is equivalent to ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=608b99c298ee8218219ddaa1]
<FromGitter> <naqvis> and above snippet is going to work, but it will be an undefined behavior
_ht has joined #crystal-lang
<FromGitter> <elementio:salt-rock-lamp.ems.host> ah
hightower2 has joined #crystal-lang
vasanth has joined #crystal-lang
hendursa1 has quit [Ping timeout: 240 seconds]
vasanth has quit [Ping timeout: 260 seconds]
hendursa1 has joined #crystal-lang
vasanth has joined #crystal-lang
mipmip has quit [Ping timeout: 240 seconds]
mipmip has joined #crystal-lang
sz0 has quit [Quit: Connection closed for inactivity]
vasanth has quit [Ping timeout: 268 seconds]
yxhuvud has quit [Read error: Connection reset by peer]
yxhuvud has joined #crystal-lang
repo has quit [Quit: WeeChat 3.0]
repo has joined #crystal-lang
oprypin has quit [Remote host closed the connection]
FromGitter has quit [Remote host closed the connection]
oprypin has joined #crystal-lang
FromGitter has joined #crystal-lang
Xeago has quit [Quit: Xeago]
Xeago has joined #crystal-lang
hightower2 has quit [Ping timeout: 240 seconds]
alexherbo2 has joined #crystal-lang
alexherbo28 has joined #crystal-lang
alexherbo2 has quit [*.net *.split]
mipmip has quit [*.net *.split]
fifr` has quit [*.net *.split]
f1refly has quit [*.net *.split]
woodruffw has quit [*.net *.split]
sagax has quit [*.net *.split]
alexherbo28 is now known as alexherbo2
mipmip has joined #crystal-lang
fifr` has joined #crystal-lang
f1refly has joined #crystal-lang
woodruffw has joined #crystal-lang
sagax has joined #crystal-lang
sagax has quit [Max SendQ exceeded]
Renich[m] has joined #crystal-lang
<FromGitter> <drum445> which orm do you guys recommend?
<FromGitter> <Blacksmoke16> clear is good if you're using PG, granite is ok for simple stuff and supports annotations on the column ivars, might also be able to just not use an ORM if its really simple
<FromGitter> <drum445> I usually avoid ORMs tbh, but I come from a dynamic lang background where it was fine to have hashes flying around (just dealing with state). ⏎ Will take a look at those two, cheers
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<FromGitter> <drum445> @Blacksmoke16 when you don't bother with an ORM, do you handwrite your SQL in your crystal files, or do you use some sort of query builder?
<FromGitter> <Blacksmoke16> tbh i havent done anything that needed a DB in a while
<FromGitter> <robear> I am new to Crystal but I have been enjoying the standard library db library - https://crystal-lang.org/reference/database/ Not an ORM if that is what you are looking for.
<FromGitter> <Blacksmoke16> fwiw pretty sure most ORMs are built on top ofthat
<FromGitter> <Blacksmoke16> mainly just providing a more OOP way of interacting with it, and abstracting some of the DB specific stuff away. But is deff pretty straightforward for simple things
mps has joined #crystal-lang
<FromGitter> <drum445> You reckon having result sets return from my DAO layer is decent enough for simple crud then?
champ20 has joined #crystal-lang
<champ20> https://play.crystal-lang.org/#/r/b17k - is it possible to do something like those comments i left below? note: cant be a simple function/method, must be a module
_ht has quit [Remote host closed the connection]
champ20 has quit [Quit: away]
<FromGitter> <erdnaxeli:cervoi.se> I don't think that's possible
<FromGitter> <erdnaxeli:cervoi.se> what are trying to solve?
<FromGitter> <Blacksmoke16> champ20 im not sure what you're wanting to do
<FromGitter> <Blacksmoke16> `.login` and `.new` should work fine, but the middle one wouldnt work
deavmi has quit [Ping timeout: 260 seconds]
deavmi has joined #crystal-lang
<FromGitter> <Blacksmoke16> (assuming you define those ofc)
<FromGitter> <Blacksmoke16> although `.new` would be super confusing as its not actually returning a new instance
<FromGitter> <watzon> @champ20 you'd be better off calling `Login` something else imo. While "login" can be a noun, it's more often a verb in a programming context, and I'd generally discourage using a verb as an object name. Maybe use `Account` or `Client` and then have a `.login` and/or a `.new` method.
<FromGitter> <watzon> And like George said, the middle isn't possible. I know in Ruby you can have a top level method with an uppercase name that acts as a constructor, but in Crystal this isn't possible.
oprypin has quit [Quit: Bye]
oprypin has joined #crystal-lang
JJEE has joined #crystal-lang
<JJEE> Hey guys, I came to ask how Crystal's package manager figures out what file has to be run when you install a module
<FromGitter> <Daniel-Worrall> I believe you mean Shards? https://github.com/crystal-lang/shards
<JJEE> yes, correct
<JJEE> in my shards.yml file i have dependencies, i install them using shards install, how does shards know what file to target when i require one module i installed?
<JJEE> thank you
<JJEE> when writing modules is using `module` necessary?