<FromGitter>
<HarrisonB> @girng I'm confused. Is this related to the discussion @Blacksmoke16 and I were having?
<FromGitter>
<girng> @HarrisonB nope, sorry for butting in lol i just thought of something and posted to gitter
<FromGitter>
<HarrisonB> no worries! I just wasn't sure how it was related haha. Are you proposing indenting the branches of a `case` block?
<FromGitter>
<girng> yeah, or maybe add it as an option in vscode crystal plugin. i was just thinking of it cuz it makes it more readable (for me)
<FromGitter>
<girng> but i'm not sure if i'm the only one :O
<FromGitter>
<HarrisonB> I think having them aligned is the standard Rubocop guideline, though I think it's configurable
<FromGitter>
<girng> i see, yeah no big deal just throwing it out there
JesseH has joined #crystal-lang
<JesseH>
For anyone using Kemal, is there a simple way to get the client information like IP? I heard if you use nginx it will pass X-Forwarded-For or something
rohitpaulk has quit [Ping timeout: 272 seconds]
rohitpaulk has joined #crystal-lang
<FromGitter>
<bararchy> @ezrast how goes the logger work? Really interested in that :)
wontruefree has joined #crystal-lang
wontruefree has quit [Ping timeout: 250 seconds]
rohitpaulk has quit [Ping timeout: 246 seconds]
Groogy1 has joined #crystal-lang
<FromGitter>
<j8r> JesseH: yes you'll need to forward the client IP in a header. If you use a reverse proxy like nginx, you need to tell it to do so
rohitpaulk has joined #crystal-lang
<FromGitter>
<j8r> I've already asked the question (sort of) - in HTTP::Client, what's the diff of having `def self.new()`with `new()` vs `def initialize()` and `initialize()`. Example https://github.com/crystal-lang/crystal/blob/master/src/http/client.cr#L213. ⏎ Do you confirm there are really no differences in performance and memory? Because initialize adds `allocate`, if I use multiple of them, do allocations multiply?
<FromGitter>
<j8r> I've tested to change all the `new` to `initialize` and it does compile
<FromGitter>
<j8r> I could benchmark, but I would know a bit more about what happens when using `initialize` inside an `initialize` :)
<FromGitter>
<bararchy> @j8r Benchmakr :) If it works faster then let us know!
<FromGitter>
<j8r> a bit slower whit initializers, 1.03x I have
<FromGitter>
<r00ster91> try putting 100.times around the code to get better results
<FromGitter>
<j8r> I've 10.30 slower with `999.times` :o
<FromGitter>
<bararchy> Oo
ashirase has quit [Ping timeout: 240 seconds]
ua has quit [Ping timeout: 246 seconds]
ashirase has joined #crystal-lang
ua has joined #crystal-lang
Groogy1 has quit [Ping timeout: 252 seconds]
rohitpaulk has quit [Ping timeout: 240 seconds]
Groogy1 has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 260 seconds]
<FromGitter>
<Schniz> hey there! I have a small question :D ⏎ is it possible to have a `while` loop in a macro? or to recursively call a macro? 🤔
<FromGitter>
<j8r> yes you can recursively call a macro
ua_ has joined #crystal-lang
<FromGitter>
<Schniz> oh right, cool cool cool
<FromGitter>
<Schniz> I forgot that I already tested it after I wrote it in gitter's text input
<FromGitter>
<Schniz> ;p
ua has quit [Ping timeout: 240 seconds]
<livcd>
bararchy: Are macs expensive in IL ?
<FromGitter>
<bararchy> livcd: I dont really know, I guess a little more then the US, but I'm using Linux on non-mac system
<FromGitter>
<Meyfarth> Hi everyone, i'm totally new to Crystal and never did Ruby, so i'm kind of lost in the syntax at the moment. From where should I start to get going ?
<FromGitter>
<fusillicode> Btw hello guys I'm kind of new too, in particular with Kemal 😅
<FromGitter>
<fusillicode> And right now I'm trying to figuring it out how a Kemal app can be configured 🤔
<FromGitter>
<fusillicode> I mean configure stuff like db credentials, basic auth and so on :D
<FromGitter>
<Meyfarth> Thanks, I already started it, I was just wondering if it was the right way to start or if there was some tutorials with concrete use cases and exemples. I'll keep digging and playing with the doc :)
<FromGitter>
<fusillicode> Well @Meyfarth it depends on what you're trying to achieve :) ⏎ I mean, if you're interested in developing a Web app I think that you can also dig into Kemal and/or Amber :) ⏎ In general I think that a good place where you can find interesting libs and projects is https://github.com/veelenga/awesome-crystal
<wontruefree>
interesting I will have to work with it more
wontruef_ has joined #crystal-lang
wontruefree has quit [Ping timeout: 252 seconds]
<FromGitter>
<HarrisonB> Asked this last evening but wasn't able to come up with a solution then: Is there a way to (using overloading) divert nillable types to a separate method?
Creatornator has joined #crystal-lang
<FromGitter>
<bew> Yes
<FromGitter>
<bew> Just restrict the argument to `Nil`
<oprypin>
but the thing is you will only be diverting the runtime value of nil
<FromGitter>
<bew> Wut oprypin? What do you mean ?
<oprypin>
a method doesn't know the compile time type of the object (T | Nil) , it will see only either T or Nil after resolution
<oprypin>
i imagine that @HarrisonB wants to detect having passed (T | Nil) rather than T
Heaven31415 has joined #crystal-lang
Creatornator has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter>
<HarrisonB> @oprypin yes, exactly
<oprypin>
HarrisonB, well there's probably a better way to do things anyway
<FromGitter>
<girng> @codenoid ok i guess i'll mkae it in crystal repo
<FromGitter>
<girng> actually nvm
<FromGitter>
<codenoid> ok
<FromGitter>
<codenoid> my coding mood is gone for 2days :
<FromGitter>
<girng> why?
<FromGitter>
<ezrast> @j8r No need to check the filesize, just keep trying to read from the file: https://carc.in/#/r/53lb. That will work better with named pipes and other things that don't have a size.
DTZUZO has joined #crystal-lang
<FromGitter>
<HarrisonB> @oprypin do you have any suggestions? I’d be happy to explain the general problem more thoroughly if you’re interested
<FromGitter>
<girng> i reduced my code into an example to show
<FromGitter>
<vladfaust> Because `new_client` may be not initialized :thinking:
<FromGitter>
<girng> i specifically set is_game_server to be a bool of either true or false
<FromGitter>
<girng> how can it EVER be nil i'm confused :/
francisl has joined #crystal-lang
<FromGitter>
<vladfaust> You're rescuing an exception without guarantee that `new_client` will be initialized
Yxhuvud has quit [Remote host closed the connection]
<FromGitter>
<vladfaust> Either do `new_client = uninitialized Client` before `begin` if you're sure it would ne initialized (higly doubt so), or handle a situation when `new_client` is nil
<FromGitter>
<vladfaust> The best approach is `new_client.try &.is_game_server`
<FromGitter>
<girng> @vladfaust i will use `new_client = uninitialized Client`, thanks
<FromGitter>
<girng> that fixes it
<FromGitter>
<vladfaust> It may lead to runtime crash, though
<FromGitter>
<girng> i'm just confused because i specifically initialized it inside the begin/rescue blocks, and it still says a property of it could be`nil`. Client.new is 100% being initialized. and the property is statically typed to a bool, true or false. how can `nil` come out of a true or false value
<FromGitter>
<girng> soo many questions lol srry just don't get it
<FromGitter>
<vladfaust> You're confused because you misread that line: `undefined method 'is_game_server' for Nil `. `is_game_server` is still `Bool`, but `new_client` is `Client | Nil`
<FromGitter>
<girng> yeah, but why is Client complaining about being | Nil when it has no reason to. i'm initializing it. i could see if that initialize fails or something, but it just has a property
<FromGitter>
<bajro17> Can someone help how to make CLI commands am I need to use process or something else?
<FromGitter>
<vladfaust> @girng Everything with `begin` block is considered "may never be executed" by the compiler. So it assumes that `new_client = Client.new ` line may never be called, therefore it's `| Nil`
<FromGitter>
<bajro17> @vladfaust @j8r Thank you both I will check mostly last link its nothing bad in self advertisement :)
<FromGitter>
<girng> Why is it assuming it will never be called when I specifically wrote that line of code for it to be initialized. Doesn't make sense
<FromGitter>
<girng> i just don't get it, unfortunately :P
<FromGitter>
<vladfaust> *Wisdom comes with experience*
<FromGitter>
<ezrast> @girng because `begin` blocks can be jumped out of early using exceptions. The compiler doesn't look inside all the methods you call to see if you actually raise an exception or not. It just assumes that anything in there can and will fail.
<FromGitter>
<girng> Yes, that's why I rescue it
<FromGitter>
<j8r> @vladfaust sensei wise he is
<FromGitter>
<j8r> 😄
<FromGitter>
<vladfaust> 🙂
<FromGitter>
<girng> to catch whatever error happens. in my case, it would be an io timeout or w/e from the tcp stream (disconnected)
<FromGitter>
<vladfaust> > @girng Everything with `begin` block is considered "may never be executed" by the compiler. So it assumes that `new_client = Client.new ` line may never be called, therefore it's `| Nil`
<FromGitter>
<vladfaust> That's is a fact (in my universe)
<FromGitter>
<vladfaust> `new_client.try &.is_game_server` is shorter
<FromGitter>
<vladfaust> It builds :)
<FromGitter>
<girng> yeah true
<FromGitter>
<ezrast> @j8r as far as I know all the IO functions either fill a Slice (which must be preallocated) or return a String (which has UTF-8 baggage) so if you want an arbitrary number of plain ol' bytes you'll need to read from the IO in a loop, yes. Maybe you can call `#gets_to_end` to get a String and then `#bytes` on the result, but I'd just write the loop.
<FromGitter>
<ezrast> `bytes = [] of UInt8; slice = Bytes.new(4096); until file.read(slice) == 0; bytes.concat slice; end` or so
<FromGitter>
<j8r> Good idea @ezrast , thank you again :)
<FromGitter>
<j8r> Do you know how `tail` work to get the last 10 lines? Does it read from the end of the file, like a `File.read_line` but starting from the bottom to the top, iterating 10 times, or something like that
DTZUZO has quit [Ping timeout: 246 seconds]
<FromGitter>
<j8r> @ezrast but then how can I convert an `Array(UInt8)` to a `String`?
<Heaven31415>
is it possible to write inline asm in crystal?
<FromGitter>
<ezrast> @j8r There's no way to read files backwards. The actual tail utility is pretty involved; IIRC what the GNU version does is looks at the file size, seeks to position (size - X) where X is some constant (16k or something), reads in the last X bytes, count the newlines, if lines >= 10 dumps the last 10 and is done, else seeks to position (size - 2X), reads in X bytes, prepends that to the original data, counts
<FromGitter>
... newlines, etc.
<FromGitter>
<ezrast> I think `String.new(arr.to_unsafe, arr.size)` works to convert Array(UInt8) -> String, but be careful because unsafe.
wmoxam_ is now known as wmoxam
wmoxam has joined #crystal-lang
wmoxam has quit [Changing host]
commavir has quit [Quit: leaving]
Heaven31415 has quit [Quit: Leaving]
commavir has joined #crystal-lang
<FromGitter>
<girng> getting the game loop portion of my game. sleep 0.067 is a godsend! man, fibers are awesome in crystal!!
<FromGitter>
<girng> i swear, this language is like perfect for game servers
<non-aristotelian>
From what I can tell, Crystal's `spawn` acts similarly to Erlang's `spawn`. And yes, that is awesome. :)
<FromGitter>
<girng> i'm just happy to a part of this timeline =]
<FromGitter>
<girng> i originally thought games.clear would close the fibers associated to them, but instead, i just set a `game_closed` to true, so it returns (which exits the fiber), before doing games.clear
<FromGitter>
<j8r> I would use an Array of Objects instead of an Hash, personally.
<FromGitter>
<j8r> And I don't what the class Gamee will become, but here it can be a struct
<FromGitter>
<bajro17> @girng You already know bro this is perfect language for everything
<FromGitter>
<Blacksmoke16> whats the rule of thumb on class vs struct
<FromGitter>
<bajro17> I just wish to start earn to more to give 100% my support to creators
<FromGitter>
<j8r> in general always use struct when possible, they are stack based.
<FromGitter>
<j8r> But sometimes you have to use classes because struct are immutable. You can't change its structure, you have to recreate one
<FromGitter>
<girng> yea i just am using a class cuz my games object is mutable in my main code there are properties that need to be changed
<FromGitter>
<j8r> you can change them
<FromGitter>
<girng> i was just curious if i'm closing the fiber correctly, of if that's how to do it (checking if a property is true per loop and return)
<FromGitter>
<Blacksmoke16> in laymen terms that means if you new up a struct with an ivar of name like
<FromGitter>
<Blacksmoke16> `Struct.new("Bob")` if you wanted to change the name property you would have to make a new one, vs doing `s.name = "foo"`
<FromGitter>
<Blacksmoke16> nvm you already answered that
<FromGitter>
<Sija> but they are passed by copy instead of a reference
<FromGitter>
<bajro17> on end it write how to choose struct or class
<FromGitter>
<bajro17> So how do you choose between a struct and a class? The rule of thumb is that if no instance variable is ever reassigned, i.e. your type is immutable, you could use a struct, otherwise use a class.
<FromGitter>
<Sija> yeah, that’s what they are for
<FromGitter>
<Sija> but they’re not immutable themselves
<FromGitter>
<Blacksmoke16> but in practice, in that example you would want to use a class if you *had* to chance the instance vars of it
<FromGitter>
<Blacksmoke16> to change*
<FromGitter>
<j8r> I would mean "You can't mutate the variable passed by copy" which is how structs are passed
<FromGitter>
<j8r> Else you if you want to share a struct, have to use a pointer, which is unsafe
<FromGitter>
<bajro17> hmmmm I dont even know crystal have pointers
<FromGitter>
<bajro17> is that mean it can work on even low level?
<FromGitter>
<j8r> In a way yes
<FromGitter>
<Sija> @Blacksmoke16 that depens on the use case, in most of the times you’d use class, but if you’re certain that your struct will not be copied than you can use that
<FromGitter>
<j8r> I always use structs, the docs aren't very clear for a beginner
<FromGitter>
<Blacksmoke16> might have to switch my stuff over
<FromGitter>
<j8r> The main pros is when you want to share the values of an Object
<FromGitter>
<Sija> @bajro17 sure, you can call C functions from within Crystal too, that’s how you can cheaply create binding, since it’s native
<FromGitter>
<bajro17> I cant wait to some smart enough make simple system based on crystal, same thing happen with golang
<FromGitter>
<j8r> Keep in mind you that the struct is copied, but the ivars that are classes are copied by reference
<FromGitter>
<j8r> I may have worded badly again :|
<FromGitter>
<bajro17> @j8r I think documentation need be much better, api is good enough but documentation will be much better with more examples
<FromGitter>
<bajro17> but I think for now priority is still language road to version 1.0
<FromGitter>
<j8r> btw you can pass by copy a class (#dup or #clone) and by reference a struct (pointer), but thats meh
<FromGitter>
<j8r> @bajro17 agree, 1.0 will reassure corporate people
<FromGitter>
<bajro17> We have pure gold but not so much people know about it :)
<FromGitter>
<bajro17> in every way I try promote crystal how much I can
<FromGitter>
<j8r> crystal-clear gold :D
<FromGitter>
<bajro17> to people see how simple, awesome and fast language exist
<FromGitter>
<bajro17> to dont mention syntax I fall in love from first day
<FromGitter>
<Sija> yeah, but I don’t think it gonna fly before some crucial issues gonna be resolved - like no incremental compilation and huuge compilation times on bigger projects
<FromGitter>
<j8r> haha, I like the high level accessibility but being able to dig deeper and deeper on lower levels to optimize
<FromGitter>
<Sija> also, no way to handle more than 4G and some others
DTZUZO has joined #crystal-lang
<FromGitter>
<bajro17> yes compilation is little problem
<FromGitter>
<bajro17> but I believe soon it will be fixed
<FromGitter>
<Sija> very “little” ;)
<FromGitter>
<bajro17> hahah yes "little"
<FromGitter>
<Sija> count me in, I’d love crystal to gain traction it deserves
<FromGitter>
<bajro17> thank you for correct me
<FromGitter>
<Sija> :P
<FromGitter>
<j8r> The big part is stabilizing the API, to reach 1.0
<FromGitter>
<Sija> windows - coming there, multi-threading - stalled for the moment
<FromGitter>
<bajro17> we really need more people to know about it because it will help in finding new bugs and issues
<FromGitter>
<Sija> huh, have you looked at the issue tracker?
<FromGitter>
<bajro17> when 1.0 come out to we all can be proud we help in development of best programming language
<FromGitter>
<bajro17> yes bro it make me little dizzy
<FromGitter>
<bajro17> hahaha
<FromGitter>
<Sija> there’s more bugs and issues than most of the devs can handle
<FromGitter>
<j8r> Some wants to lazily use the language, and to bot worry about breakages – and I understand
<FromGitter>
<j8r> The Elixir project has so few issues and PRs 😮