ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.29.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
blassin278 has joined #crystal-lang
blassin27 has quit [Read error: Connection reset by peer]
alex`` has quit [Read error: Connection reset by peer]
sorcus has quit [Ping timeout: 264 seconds]
<FromGitter> <mwlang> what's crystal's equivalent to Ruby's *FILE* (or current script filename)?
<FromGitter> <Blacksmoke16> `__FILE__`
<FromGitter> <mwlang> hmmm...markdown got me there. :-p
<FromGitter> <mwlang> ok, giving that a go.
<FromGitter> <mwlang> So, is it likewise idiomatic in Crystal to rely on `__FILE__` for figuring out relative paths, etc.?
<FromGitter> <Blacksmoke16> dunno
absolutejam2 has joined #crystal-lang
absolutejam2 has quit [Ping timeout: 245 seconds]
mistergibson has joined #crystal-lang
snsei__ has joined #crystal-lang
snsei__ has quit [Remote host closed the connection]
duane has quit [Ping timeout: 244 seconds]
<FromGitter> <mwlang> how do you do compound YAML mappings...can't seem to find a documented example: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1ebaf95e957c4d48d31081]
<FromGitter> <mwlang> I end up with this error: Syntax error in expanded macro: mapping:34: expecting token 'CONST', not 'nil' @binance : nil
<FromGitter> <mwlang> nevermind, I just stumbled upon YAML serializable. That's just like JSON, so I'll go that route.
duane has joined #crystal-lang
flaviodesousa has quit [Ping timeout: 248 seconds]
flaviodesousa has joined #crystal-lang
<FromGitter> <watzon> Yeah what you were trying isn't possible
duane has quit [Ping timeout: 258 seconds]
laaron has joined #crystal-lang
<wmoxam> Any chance that Crystal will support LLVM > 6 anytime soon?
absolutejam2 has joined #crystal-lang
absolutejam2 has quit [Ping timeout: 248 seconds]
absolutejam2 has joined #crystal-lang
absolutejam2 has quit [Ping timeout: 258 seconds]
mistergibson has quit [Quit: Leaving]
absolutejam2 has joined #crystal-lang
<FromGitter> <naqvis> Thanks Julien @j8r. tarball is just a reader of archive with limited support. What I put together is complete reader/writer supporting major format.
<absolutejam2> how do I define a logger singleton since globals have been removed?
<FromGitter> <watzon> @absolutejam2 on your main module you can do `class_getter logger = Logger.new` and then you can access it from anywhere by doing `MyModule.logger`
<FromGitter> <watzon> If I understood your question correctly
<absolutejam2> ty
<FromGitter> <watzon> Np
absolutejam2 has quit [Ping timeout: 244 seconds]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
<FromGitter> <vladfaust> @bararchy what’s the usecase? I hardly can imagine where I do need string enums πŸ€”
DTZUZO has quit [Ping timeout: 245 seconds]
<FromGitter> <girng> string enums??
<FromGitter> <girng> doesn't that make the performance of enums slower
<FromGitter> <girng> and completely nullify the entire reason of using enums in the first place?
<FromGitter> <girng> or, is it just a syntax sugar change, but works fast still under the hood?
<FromGitter> <vladfaust> I guess. One could simply do `case myenum; when foo? "foo"` etc
<FromGitter> <bararchy> ```def select(selector : Selector) ⏎ ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5d1f0060f24e3f5ec75c7b3b]
absolutejam has quit [Quit: WeeChat 2.5]
<FromGitter> <bararchy> @vladfaust it looks nicer, and allows me to also MAKE the user choose one of the avilable options without raiseing if he used something unsupported
<FromGitter> <vladfaust> > ⏎ ⏎ ```def select(selector : Selector) ⏎ end``` ⏎ ⏎ How would the call look like? [https://gitter.im/crystal-lang/crystal?at=5d1f01bdb5d39c1bfef52f15]
absolutejam2 has joined #crystal-lang
<FromGitter> <bararchy> you mean the code inside the `select` method? or calling the `select` method ?
<FromGitter> <vladfaust> Both =)
<FromGitter> <bararchy> ```code paste, see link``` ⏎ ⏎ It's part of the WebDriver protocol [https://gitter.im/crystal-lang/crystal?at=5d1f0243f24e3f5ec75c7b3d]
<FromGitter> <vladfaust> Confusing to see it w/o `.to_s`. From C-family languages perspective (and also Crystal, as I've got used to it), `selector` is clearly a numeric value, because it's enum
absolutejam has joined #crystal-lang
<FromGitter> <bararchy> that's a differernt problem all together XD
<FromGitter> <bararchy> but in my eyes, it's the 3rd time I wished we had a String enum
<FromGitter> <bararchy> or more prefferebly, a Object Object enum
<FromGitter> <vladfaust> No language firs every use-case. IMO, knowing that enum is always a numeric value gives more advantage than generic Object enums
<FromGitter> <yxhuvud> @bararchy is that really a problem best solved by an enum? You could create a class for each variant, and implement a common method on it, so that instead of just doing `value: selector` you would do `value: selector.foo`.
<FromGitter> <yxhuvud> or not even that if you made the class support json serialization. to_json calls itself on each value in a hash, right?
<FromGitter> <watzon> The enum way sounds like much less and f a hassle. More efficient too.
sorcus has joined #crystal-lang
<FromGitter> <Prutheus> I have a string `"1-16 von mehr als 1.000 Ergebnissen oder VorschlΓ€gen fΓΌr erkmann - wohnen design geschenke"` where i wanna get all numbers via regex (regex: `([0-9.]*[0-9]+)`) ... works, check here: https://regex101.com/r/rRmGWy/1
<FromGitter> <Prutheus> now, my crystal code: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ does not work: ... [https://gitter.im/crystal-lang/crystal?at=5d1f1448b5d39c1bfef5d3dd]
absolutejam has quit [Quit: WeeChat 2.5]
absolutejam has joined #crystal-lang
<FromGitter> <Prutheus> no-one here at the moment?
<FromGitter> <mavu> @Prutheus I think that is expected behaviour. regexps match once, and return that match. ⏎ In ruby for example, you get the exaxt same behaviour, and if you wanted all matches, your would use the .scan() method.
<FromGitter> <bew> I second @mavu, your regex101 link works because there is a `g` (for `global`) regex option, that make it search all the matches, not just the first one.
<FromGitter> <Prutheus> what is the crystal function for scan?
<FromGitter> <bew> `String#scan(regex)`
<FromGitter> <bew> e.g: https://carc.in/#/r/76n7
<FromGitter> <bew> or you can call it without a block, and it'll return an array of all the matches
<FromGitter> <Prutheus> okay. now a second question ... how to delete all empty strings from an array?
<FromGitter> <Prutheus> how to drop them
<FromGitter> <Prutheus> is there a fancy function for that?
<FromGitter> <Prutheus> doesn't matter
<FromGitter> <Prutheus> solved
DTZUZO has joined #crystal-lang
<FromGitter> <bew> `arr.reject!(&.empty?)` for example
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
<FromGitter> <alexherbo2> Hi
<FromGitter> <Blacksmoke16> o/
<FromGitter> <alexherbo2> What is the Crystal equivalent for this JS code? https://youtu.be/lhZOFUY1weo?t=312
<FromGitter> <bestwebua> Idea for new ```.compact``` feature, opportunity use it with block, like ```arr.compact(&.empty?)```
<FromGitter> <alexherbo2> Trying to play with sockets
<FromGitter> <alexherbo2> It’s created by running `chromium --remote-debugging-port=9222`
<FromGitter> <Blacksmoke16> @alexherbo2 my understanding is you just https://crystal-lang.org/api/master/HTTP/WebSocket.html#new%28host%3AString%2Cpath%3AString%2Cport%3Dnil%2Ctls%3Dfalse%2Cheaders%3DHTTP%3A%3AHeaders.new%29-class-method
<FromGitter> <Blacksmoke16> new up a WS, then can invoke the `#send` method to send data to that WS
<FromGitter> <alexherbo2> there is no need to on_open or something?
<FromGitter> <alexherbo2> ```require "http/web_socket" ⏎ ⏎ HTTP::WebSocket.new(URI.parse("http://localhost:9222"))``` [https://gitter.im/crystal-lang/crystal?at=5d1f4fc407d71829adb89df0]
<FromGitter> <alexherbo2> just that?
<FromGitter> <Blacksmoke16> im not super familiar with them, but yea
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f4ffac5f3c329aeed0dd2]
<FromGitter> <girng> look at kemal's ws api
<FromGitter> <girng> close to that example u ognna get
<FromGitter> <Blacksmoke16> prob
<FromGitter> <Blacksmoke16> he's prob just wrapping the stdlib
<FromGitter> <alexherbo2> I tried this
<FromGitter> <alexherbo2> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f511511bfea0b67aa98cb]
<FromGitter> <girng> yeah
<FromGitter> <alexherbo2> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f5129ccfbb80e4142b3ec]
<FromGitter> <girng> wtf
<FromGitter> <alexherbo2> can you try doing this (without other chrome instances)
<FromGitter> <alexherbo2> ```chromium --remote-debugging-port=9222```
<FromGitter> <alexherbo2> and the code above
duane has joined #crystal-lang
duane has quit [Ping timeout: 246 seconds]
duane has joined #crystal-lang
snsei__ has joined #crystal-lang
<FromGitter> <Blacksmoke16> `http://localhost:9222/json` i dont think this is the right url
<FromGitter> <Blacksmoke16> should prob be like `ws://localhost:9222/json`
<FromGitter> <Blacksmoke16> @alexherbo2
<FromGitter> <Blacksmoke16> since you want websocket connection vs http
<FromGitter> <mwlang> Whoever pulled these together, a big Thank You! https://github.com/crystal-community/crystal-patterns
<FromGitter> <mwlang> quickly finding answers to how to implement these patterns as I get started on my first app development in Crystal.
<FromGitter> <mwlang> apps and shards can be two different beasts in many ways.
<FromGitter> <mwlang> @alexherbo2 I don't know if this can help, but maybe spark an idea for you: https://gist.github.com/mwlang/57876320390c899be690a5a79eed8125
<FromGitter> <mwlang> it's not an entirely correct implementation, but the websocket parts do work.
mistergibson has joined #crystal-lang
<FromGitter> <mwlang> what's the difference between delegate and forward_missing_to?
<FromGitter> <mwlang> I guess with forward_missing_to every missing method signature is delegated? whereas delegate, you single out specific methods to delegate?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <mwlang> πŸ‘
absolutejam2 has quit [Ping timeout: 268 seconds]
<FromGitter> <mobilpadde_gitlab> Hi! How would I go if I have a fiber, unless that fiber has finished I want to put some text every x second. Once finished it'd put something else? Thanks!
<FromGitter> <mwlang> Send message in channel to main loop and print out that message.
<FromGitter> <mobilpadde_gitlab> So, like send a message to a channel once it's supposed to finish, and in the main I'd put a `until` to check if finished?
<FromGitter> <mwlang> oh, you're wanting opposite way around than what I was thinking, but yes, when fiber finishes, it should send a signal on the channel that it completed it's work.
<FromGitter> <mwlang> the main loop then just checks every second until that message is received.
<FromGitter> <mobilpadde_gitlab> Tried to, though can't figure how to do it :/ ⏎ ⏎ Tried something like this: ⏎ ⏎ ```code paste, see link``` ... [https://gitter.im/crystal-lang/crystal?at=5d1f7222b682244d4989b2d7]
<FromGitter> <mwlang> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f72c7c5f3c329aeee5d93]
<FromGitter> <mobilpadde_gitlab> I'm quite new, just started using crystal today :p And never used ruby before, though I fell in love with it! :D
<FromGitter> <mobilpadde_gitlab> Oh, nice! Thanks!
<FromGitter> <mobilpadde_gitlab> Will test
<FromGitter> <mwlang> I'm new to Crystal as well, but coming from Ruby background.
<FromGitter> <mwlang> This fiber thing was first thing I was tackling myself. Definitely read through this: https://crystal-lang.org/reference/guides/concurrency.html That got me up to speed pretty quickly.
<FromGitter> <mobilpadde_gitlab> Yea, read that :D
<FromGitter> <mobilpadde_gitlab> Hmm, could this be done like ⏎ ⏎ ```if ch.receive? ⏎ puts "Hai!" ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5d1f73a0a0a38158f1a8b7a6]
<FromGitter> <Blacksmoke16> no, it'll block until there is data in the ch
<FromGitter> <Blacksmoke16> i mean, if you just want to wait for something to finish that would do it
<FromGitter> <Blacksmoke16> i.e. program would hit that, wait for fiber the send a value, then hit that if statement
<FromGitter> <yxhuvud> I think it is possible to do by selecting over multiple channels, where one channel is a fiber that simply fires an event every once in a while
<FromGitter> <mobilpadde_gitlab> Okay, thanks!
<FromGitter> <mobilpadde_gitlab> Managed to get it working by ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f74a8c5f3c329aeee7106]
<FromGitter> <mobilpadde_gitlab> Wait, now my first fiber won't fire?
<FromGitter> <Blacksmoke16> is the end goal here to just have a bunch of fibers run and wait until they all done?
<FromGitter> <mobilpadde_gitlab> One fiber doing some heavy lifting, and something else sleeping for like a sec, put some content, then stopping when the fiber is done
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/toplevel.html#parallel(*jobs)-macro
<FromGitter> <Blacksmoke16> could maybe use this?
<FromGitter> <Blacksmoke16> but prob not since you would need to communicate when the heavy fiber is done to the puts fiber
<FromGitter> <mwlang> ugh! still struggling with the pattern of passing on the object I'm initializing to the child objects I want to create while in the initialize constructor.
<FromGitter> <mwlang> almost like I'm going to have to start doing Factory patterns to build in two steps if I want to continue thinking this way.
<FromGitter> <mwlang> yeah, that's what I'm gonna do. I don't remember Delphi having this issue with it's constructor.
<FromGitter> <mwlang> So I wonder why Crystal can't have proper access to "self" inside #initialize calls
<FromGitter> <mwlang> sure it may not be fully initialized yet, but surely the pointer to "self" can be obtained and set in child classes and it'll all tie together later when accessed.
<FromGitter> <girng> https://play.crystal-lang.org/#/r/76p0 @mwlang ?
<FromGitter> <Blacksmoke16> they do the same thing but the first one is calling the setter, while the latter is directly settings it
<FromGitter> <girng> what does "proper access to self" mean, afaik it's working like most selfs i've seen
<FromGitter> <naqvis> @mwlang have you looked into `Hooks`? Believe `finished` macro is what you are upto? ⏎ ⏎ https://crystal-lang.org/reference/syntax_and_semantics/macros/hooks.html
<FromGitter> <Blacksmoke16> id need to see an example if you want to make a playground
<FromGitter> <girng> but.. then again, i'm the kind of the person who would do... `p = Test.new`, then `p.name = "Korale"` LOL
<FromGitter> <Blacksmoke16> easiest way is to just do like `def initialize(@name : String); end` then `p = Test.new "Name"`
<FromGitter> <girng> ye true
<FromGitter> <mwlang> @naqvis I didn't know about `Hooks` Reading up now...
<FromGitter> <mwlang> I think I have it working now. https://play.crystal-lang.org/#/r/76p8 is the "contrived example" and I got it working in the playground.
<FromGitter> <girng> what is a "dynamic library"?
<FromGitter> <girng> example please
<FromGitter> <Blacksmoke16> can clean it up a bit https://play.crystal-lang.org/#/r/76pa @mwlang
<FromGitter> <mwlang> turns out, the key was to set the getter directly in the initialization. Then I could call another method after that to populate the getter's array with objects.
<FromGitter> <mwlang> my use case is that I'm initializing my connection to Binance exchange as a BinancePortal object and immediately assigning all the markets (ticker symbols) at the outset. So it's the BinancePortal instance that self-populates it's array of markets.
<FromGitter> <girng> :D
<FromGitter> <mwlang> @girng reading that ticket, I'd say they're talking about using crystal to write dynamically linked libraries.
<FromGitter> <mwlang> basically external libraries that provide useful collection of functionality to other apps to link/bind to.
<FromGitter> <girng> ohhh dynamically linked libarires like DLLs
<FromGitter> <mwlang> like writing libxml or imagemagick in Crystal instead of C.
<FromGitter> <mwlang> yes.
<FromGitter> <girng> i was thinking of a shard or somethign that "dynamically updates" based on crystal version or something lol
<FromGitter> <girng> i was like don't we already have shards
<FromGitter> <mwlang> I can see that.
<FromGitter> <girng> everyone else got it though, sometimes i derp
<FromGitter> <girng> heheheh
<FromGitter> <girng> hey @mwlang just curious
<FromGitter> <girng> Where did you hear about Crystal?
<FromGitter> <mwlang> I'm sure from my Ruby sphere. I've known about Crystal for about 5, maybe 6 years now and periodically tried it out here and there over the years.
<FromGitter> <mwlang> but it was only recently that I had a use case powerful enough to warrant adopting and using Crystal.
<FromGitter> <girng> wow really
<FromGitter> <mwlang> I've been a Ruby developer since 2006
<FromGitter> <mwlang> and can build pretty much anything I need using Ruby...but recently, I'm handling so much data that is time-sensitive that I needed a compilable language like crystal to get the speed.
<FromGitter> <girng> That's awesome, I came from nodejs lol
<FromGitter> <mwlang> I use nodejs as well.
<FromGitter> <girng> I actually never even used Ruby before, but boy do I like the syntax!!
<FromGitter> <mwlang> or really, webpack embedded into Ruby on Rails projects.
<FromGitter> <mwlang> me too. once you master it, you can really pack a punch in only a few lines of code and it remains highly readable.
<FromGitter> <girng> so true
<FromGitter> <girng> in js i really like objects, i like how in crystal we can create a Class, then do property xxx and access it by dot notation, like an object
<FromGitter> <mwlang> I'm loving the fact that I can "think in Ruby" and more or less get to where I was headed with crystal.
<FromGitter> <girng> feels good, i like oop
<FromGitter> <mwlang> that's exactly what I was doing with the binance shard....turning all that JSON into class objects.
<FromGitter> <girng> have you noticed any performance improvements already
<FromGitter> <mwlang> HUGE
<FromGitter> <girng> lol awesome
<FromGitter> <girng> if you got time, it sounds interesting what youa re doing. i'd love to read a blog post about it
<FromGitter> <girng> comparison from ruby speed to crystal
<FromGitter> <mwlang> I was computing bollinger bands from thousands of candles (stock market charts)
<FromGitter> <mwlang> 19 minutes in Ruby vs. 3 seconds in Crystal
<FromGitter> <girng> Dang
<FromGitter> <mwlang> A lot of it was shared in this gitter...you just have to scroll up long enough to find it. :-)
<FromGitter> <girng> yea those numbers and floats in strings from api lol
<FromGitter> <mwlang> keep on going back and you'll find some performance metrics from when I first started.
<FromGitter> <Blacksmoke16> > in js i really like objects, i like how in crystal we can create a Class, then do property xxx and access it by dot notation, like an object ⏎ ⏎ Yet you dont really use them in crystal :P
<FromGitter> <girng> :D
<FromGitter> <girng> I use em for my Player class lol
<FromGitter> <girng> but yeah, i should be doing more OOP
<FromGitter> <girng> especially in game dev i think it helps a lot
<FromGitter> <mwlang> actually, search for "bollinger" That'll get you close to the conversation.
<FromGitter> <mwlang> OOP is especially suited to game development.
<FromGitter> <girng> yeah it works well doesn't it
<FromGitter> <girng> i mean, i use OOP. but i pass stuff to functions a lot since classes are pased by reference in crystal
<FromGitter> <mwlang> well, you're building an interactive world of "objects" might as well apply OOP to the modeling of your domain. :-)
<FromGitter> <girng> i just find it easier for a function to do something
<FromGitter> <mwlang> A lot of people do.
<FromGitter> <girng> on a class, instead of that class modifying itself
<FromGitter> <girng> (if that makes sense)
<FromGitter> <mwlang> well, service pattern sounds like what you just described for the former.
<FromGitter> <Blacksmoke16> i think he means he does ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f863da0a38158f1a96d59]
<FromGitter> <Blacksmoke16> vs just doing `c.do_something`, which modifies itself
<FromGitter> <girng> i don't even use `c : MyClass`
<FromGitter> <Blacksmoke16> 😐
<FromGitter> <girng> i just pass it in lmaoo
<FromGitter> <Blacksmoke16> not getting any type safety then
<FromGitter> <girng> if crystal compiler don't complain, i'm game
<FromGitter> <Blacksmoke16> *sigh*
<FromGitter> <girng> all my type safety's are done in property xxx : Type
<FromGitter> <girng> i don't use type safety for arguments
<FromGitter> <Blacksmoke16> prob should
<FromGitter> <Blacksmoke16> for how easy it is to add
<FromGitter> <girng> well, if crystal complained about it i prob would have. i just did trial an error and if it works and no compiler errors, i just continue to code lol
<FromGitter> <girng> but i mean i should...
<FromGitter> <Blacksmoke16> and you should write tests πŸ˜‰
<FromGitter> <girng> -_-
<FromGitter> <girng> `-_-`
<FromGitter> <mwlang> OOP + unit tests => readable, testable, awesome code.
<FromGitter> <Blacksmoke16> πŸ’―
<FromGitter> <Blacksmoke16> hes just gotten lucky
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/76pj like this works with and without the arg type restriction
<FromGitter> <mwlang> just wait until he has 5,000 lines of code. :-D
<FromGitter> <Blacksmoke16> he probably does
<FromGitter> <Blacksmoke16> that could be made into 1000 with a refactor xD
<FromGitter> <girng> i mean take a look at this
<FromGitter> <girng> why do i need type safety if c is 100% going to be the `MyClass`??
<FromGitter> <Blacksmoke16> imo so at a glance you know actually the type of that arg
<FromGitter> <girng> true
<FromGitter> <girng> does it make it more readable doesn't it
<FromGitter> <Blacksmoke16> also would allow you to get into overloading
<FromGitter> <Blacksmoke16> i.e. something like
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/76po
<FromGitter> <Blacksmoke16> define the same method multiple times with diff restrictions, and complier knows how to route each method call based on the type
<FromGitter> <girng> ROFL
<FromGitter> <girng> i would never use 2x some_method's though
<FromGitter> <girng> that doesn't look right
<FromGitter> <girng> 2 of the same method names... WTF
<FromGitter> <Blacksmoke16> that take diff types
<FromGitter> <mwlang> hey, that's the good stuff. :-)
<FromGitter> <girng> nah, i differentiate methods by name, not types
<FromGitter> <Blacksmoke16> but then you would need to do like
<FromGitter> <girng> if you do it with types = more confusing
<FromGitter> <Blacksmoke16> not really
<FromGitter> <girng> cause by this logic, you could have tons of some_method's
<FromGitter> <girng> and the developer now has to look at the arguments and class first, instead of just the method name
<FromGitter> <girng> convoluted af
<FromGitter> <Blacksmoke16> ```pp "foo".sub 'f', "b" ⏎ pp "foo".sub "f", "b" ⏎ pp "foo".sub /f/, "b"``` [https://gitter.im/crystal-lang/crystal?at=5d1f8885bf25f013e7cb536b]
<FromGitter> <Blacksmoke16> thats whats going on in a good amount of methods
<FromGitter> <Blacksmoke16> `sub` method for example is defined with various restrictions that allow it to work given, in this case, a char, string, and regex
<FromGitter> <Blacksmoke16> SO you could then use a common method that knows what to do no matter that type given to it
<FromGitter> <Blacksmoke16> vs having to do like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f88f03a1e451bfda70e6c]
<FromGitter> <Blacksmoke16> which would not be a compile time error
<FromGitter> <Blacksmoke16> vs just doing `sub value, "replacement"`
<FromGitter> <girng> crystal compiler is smart enough
<FromGitter> <girng> it'll give you an error before compiling if you try to do something stupid
<FromGitter> <Blacksmoke16> in your case yes
<FromGitter> <Blacksmoke16> but what about this
<FromGitter> <girng> but yeah, the types and methods happen a lot on the internal crystal methods it helps the developer
<FromGitter> <girng> but as a developer writing their own code, i think it will confuse them more
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/76pu
<FromGitter> <girng> for example, having duplicate method names littered all over, that's crazy
<FromGitter> <Blacksmoke16> your method will alter *ANY* type that has a `name=` method
flaviodesousa has quit [Quit: KVIrc 4.9.3 Aria http://www.kvirc.net/]
<FromGitter> <girng> but the method is created specifically to interact with that class
<FromGitter> <girng> so that would never happen
<FromGitter> <Blacksmoke16> name is common enough where it could
<FromGitter> <Blacksmoke16> the point of all this is reducing the changes that a bug could happen
<FromGitter> <Blacksmoke16> which you can solve via `c : MyClass`
<FromGitter> <Blacksmoke16> now you know that will never happen
<FromGitter> <girng> i like that
<FromGitter> <girng> but that's about as far asi'll go
<FromGitter> <girng> in terms of type safety
<FromGitter> <girng> i feel like crystal's compiler will detect most of this crap in advance, if you can get it compiled you should be fine
<FromGitter> <Blacksmoke16> that compiled but would have a bug at runtime
<FromGitter> <Blacksmoke16> it can only catch so much
<FromGitter> <girng> depends if the dev writes bad code
<FromGitter> <mwlang> typing the method parameters can allow you to intentionally restrict what's coming in. Sometimes you want it open (as you do here) and sometimes you *don't* -- it's a design/implementation decision and at least with Crystal, you can enforce (or choose not to)
<FromGitter> <Blacksmoke16> tests would have picked that up
<FromGitter> <naqvis> I can see that @girng still used to JS writing of functions. Your code might be clear to you, but it would be difficult for other developers to read and understand? As looking at the method signature, there is no way in knowing what type of object or argument your method is expecting
<FromGitter> <mwlang> with Ruby, you can't. You'll have to add guards in the method's implementation to enforce incoming type restrictions.
<FromGitter> <naqvis> and i’m sure you will have to go through whole code base again if you revisit your code after some break :)
<FromGitter> <girng> well, imo, having multiple method names of the same exact name scattered throughout code is far more confusing than simply not using `c : MyClass` on an argument for 1 unique method, that modifies 1 certain type of class..
<FromGitter> <mwlang> one thing I'm happy about with Crystal. There's a whole swath of unit tests I no longer have to write.
<FromGitter> <girng> different strokes for different folks, I guess
<FromGitter> <Blacksmoke16> if mean if each of those methods is doing a similar thing, it would be more clear to have them named what they do, vs what that do it to
<FromGitter> <mwlang> well, it's not impossible to code your way and it's obviously working for you, so no harm in that. But I can definitely say you're coding harder than you have to overall because you close off a good deal of power of the language to your use.
<FromGitter> <Blacksmoke16> then you can easily figure out which one it is, based on the type you're passing (as they would all be restricted)
<FromGitter> <Blacksmoke16> ^^
<FromGitter> <naqvis> yup, also your approach break the very basic tenant of OOP, that is encapsulation as you are mutating object outside the class where it is defined :)
<FromGitter> <girng> if crystal starts complaining about not having c : MyClass in the argument, i'll fix it. otherwise, I think crystal knows it's going to be that type, and that method is ONLY EVER going to be used with that class, there is literally no chance of a bug ever happening. That method is tied to that object. Only way a bug would happen is if I pass in the wrong object, but crystal would already detect that, and I would
<FromGitter> ... never do that, because that method is for that specific class anyway. Littering your code with duplicate method names and redundant type safety checks that are not even needed, is not good code.
<FromGitter> <naqvis> I agree, every one has his/her own preferred approach of writing code. Coding is just a fun, so let’s do it in a way, which makes one happy
<FromGitter> <Blacksmoke16> > Only way a bug would happen is if I pass in the wrong object, but crystal would already detect that, ⏎ ⏎ It wouldnt if it happened to have the same methods
<FromGitter> <mwlang> and then look at how I use those here: (same file) https://github.com/mwlang/binance/blob/master/src/binance/client/rest/endpoints.cr#L226-L234
<FromGitter> <Blacksmoke16> the type restriction would solve, (or better yet have the method within the class versus being a separate def out in top level)
<FromGitter> <girng> i think that's cool and makes sense in terms of creating an API
<FromGitter> <girng> but for a specific hobby project, redundant method names that are the same is silly
<FromGitter> <Blacksmoke16> got an ETA when its going to be released?
<FromGitter> <mwlang> well, for me, I knew my method to get an optional parameter added to the params object was called `#optional_param` and that's all I needed to remember vs. optional_param_from_s, optional_param_from_int32, etc.
<FromGitter> <Blacksmoke16> ☝️ July 5, 2019 1:37 PM (https://gitter.im/crystal-lang/crystal?at=5d1f8af6dd0b530e40a37db0)
<FromGitter> <Blacksmoke16> yup ^
<FromGitter> <girng> i mean look at all the type inferences crystal does
<FromGitter> <girng> crystal wants you to write basic code
<FromGitter> <Blacksmoke16> you could write terrible code and it would happily compile
<FromGitter> <girng> that is readable, less convoluted, and makes sense
<FromGitter> <Blacksmoke16> just because it complies doesnt mean its *good* code
<FromGitter> <girng> i agree, dev still has to write good code, but it's pretty hard to write bad code with crystal
<FromGitter> <mwlang> nobody saying they don't love that aspect of Crystal. ;-) I love it myself and leverage here and there...when I *think* there's a risk of misuse, I'll add the type declarations to the method call signature to keep things sane.
<FromGitter> <girng> if you can get crystal to compile, chances are, you have decent code
<FromGitter> <Blacksmoke16> not true :P
<FromGitter> <Blacksmoke16> i can only imagine the nightmare that would be making a PR to @girng's game
<FromGitter> <girng> the only time i wrote bad code in crystal is when i assigned a const array to a new property, it was referenced to all the players
<FromGitter> <Blacksmoke16> have a feeling you're the only one that can dev on it
<FromGitter> <girng> crystal never told me that
<FromGitter> <girng> that is the only bug i had that would have screwed me over
<FromGitter> <girng> that is a developer writing bad code
<FromGitter> <girng> (me)
<FromGitter> <girng> developer would think since you are creating a new array foreach time that class is initialized, it's getting a new array for that property. doesn't happen if that instance variable references a const array
<FromGitter> <girng> crystal should actually tell the developer this imo
<FromGitter> <Blacksmoke16> how would it know
<FromGitter> <Blacksmoke16> arrays are passed by reference
<FromGitter> <girng> good question iuno
<FromGitter> <Blacksmoke16> we'll convince you one of these days
<FromGitter> <girng> @Blacksmoke16 look here
<FromGitter> <girng> i'm sure crystal could warn the developer somehow
<FromGitter> <Blacksmoke16> i mean but how would it know thats *not* what they want?
<FromGitter> <Blacksmoke16> each obj is going to reference the same const array
<FromGitter> <girng> you could say that about any warning
<FromGitter> <Blacksmoke16> which is the expected behavior
<FromGitter> <girng> why is the array being referenced through a separate class initialization though
<FromGitter> <Blacksmoke16> because they are pointing to the same constant
<FromGitter> <girng> the reference to that const array points back to the first one? even if you had 1000 instanced classes?
<FromGitter> <Blacksmoke16> so the array in each reference the same instance of the array
<FromGitter> <Blacksmoke16> right
<FromGitter> <Blacksmoke16> because thats what you're assigning the property
<FromGitter> <girng> interesting
<FromGitter> <girng> didn't know references go that deep, it's literally linked everywhere char_img is set then
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/76qe yes
<FromGitter> <Blacksmoke16> another examle ^
<FromGitter> <girng> oh damn, good lord
<FromGitter> <girng> nested
<FromGitter> <girng> f*ck const arrays
<FromGitter> <Blacksmoke16> i mean it doesnt really have anything to do with it being a constant...
<FromGitter> <girng> when i first did this, i thought the references are linked to the instanced class. not ALL instant classes
<FromGitter> <naqvis> ```code paste, see link``` ⏎ ⏎ Looking at your example, I understand you are expecting to have separate copies, then you should invoke `#dup` method instead [https://gitter.im/crystal-lang/crystal?at=5d1f9148076ffa65b0545b52]
absolutejam2 has joined #crystal-lang
<FromGitter> <mwlang> I'm actually surprised by this example...a CONST defined was allowed to change through dynamic assignments.
<FromGitter> <mwlang> Ruby would bark at this.
<FromGitter> <girng> @Blacksmoke16 ^^^^
<FromGitter> <Blacksmoke16> it didnt change, it was mutated
<FromGitter> <mwlang> heh, ok, mutated. It should be immutable.
<FromGitter> <naqvis> @mwlang , const is only for ref, not for the object it is pointing to
<FromGitter> <Blacksmoke16> yea, only means it cant be reassigned
absolutejam3 has joined #crystal-lang
<FromGitter> <naqvis> that’s normal behavior in all languages including Java, C#, Go
<FromGitter> <girng> @naqvis yeah i used an array literal / dup for the fix
<FromGitter> <girng> fix in the sense of me writing bad code, not issue with language
<FromGitter> <mwlang> not sure if we're talking about the same thing, but I just mean that CHAR_IMG, once initially assigned [0,0,0,0] should cause a compiler error if it's somehow changed at later point to [1,0,0,0]
absolutejam2 has quit [Ping timeout: 246 seconds]
<FromGitter> <Blacksmoke16> eh, depends on how you look at it...
<FromGitter> <girng> when a player equips a wep/armor/boot/glove/shield, this array gets updated. so just saying, this would have been the worst bug ever to catch, everyone would complain their characters are being updated with the wrong items equipped. as the last player on that instance server who equipped an item, that char_img would be changed for everyone looooool
<FromGitter> <naqvis> CHAR_IMG is a constant which is pointing to reference to an Array. Array itself is an object. You can’t re-assign CHAR_IMG, but you can definitely mutate the object
<FromGitter> <Blacksmoke16> yea, but one could argue they would expect it to not be able to be changed at all since its a constant
<FromGitter> <mwlang> I guess, crystal doesn't have concept of FOO = [0,0,0,0].freeze
<absolutejam3> whenever I see `def initialize(@foo)` I think there should be a nice notation to end the method on the same line
<absolutejam3> if that's all that is needed
<FromGitter> <Blacksmoke16> or in typescript land like `readonly const foo = [0,0,0,0];`
<FromGitter> <Blacksmoke16> er i think that allows it to be mutated as well
<FromGitter> <girng> what's diff between a mutable const and a regular const?
<absolutejam3> like Elixir has `def foo(a), do: a` for single line declaration (although, different intent from what I'm saying)
<FromGitter> <girng> i thought constants are immutable
<absolutejam3> Haven't tried `def initialize(@foo); end` to be honest, but looks a bit clumsy
<FromGitter> <girng> or, does it depend on the language the developer is using
<FromGitter> <Blacksmoke16> would have to do like `const foo: ReadonlyArray<number> = [0,0,0,0];`
<FromGitter> <mwlang> crap...without "freeze" even Ruby lets you change constants' values
<FromGitter> <Blacksmoke16> :P
<FromGitter> <Blacksmoke16> time for a `readonly` keyword? :P
<FromGitter> <mwlang> but I've gotten pretty habitual in defining constants with #freeze, so actually kind of forgotten this!
<FromGitter> <naqvis> its normal semantic as `const` only affect the assignment operator and the object isn’t really constant, unless its an object of some immutable class
<FromGitter> <mwlang> or just tacking on `.freeze`
<absolutejam3> `let` is getting common for readonly
<FromGitter> <Blacksmoke16> thats what `ReadonlyArray` in TS does, removes mutable methods (from the interface)
<FromGitter> <girng> damn, it gets referenced infinitely i think
<FromGitter> <girng> that's normal tho, right
<FromGitter> <Blacksmoke16> well yea, they all share a reference to the same array
<FromGitter> <girng> since it's a reference
<FromGitter> <girng> that's actually pretty cool
<FromGitter> <girng> how references work
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <girng> it's all linked
<FromGitter> <girng> together
<FromGitter> <mwlang> well, @girng it's one way to do singleton pattern. :-p
<FromGitter> <girng> hell, more use-cases for my oop modifying methods ;D
<FromGitter> <girng> love me some pass by references, eh
<FromGitter> <Blacksmoke16> oh boy
<FromGitter> <girng> πŸ˜†
<FromGitter> <naqvis> @girng go with `struct` instead, if you are not expecting pass by ref πŸ˜„
<FromGitter> <girng> pass by value eh
<FromGitter> <girng> structs can have references in them..
<FromGitter> <girng> interesting
<FromGitter> <girng> oh this is gonna be a good question, one second
<absolutejam3> is there a good clarification of (in a class) getter/property/@foo anywhere?
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Blacksmoke16> like what each does?
<absolutejam3> yeah. I tried @foo earlier then found I couldn't append to it; is that purely a getter method?
<FromGitter> <Blacksmoke16> `@foo` is a "private" ivar
<FromGitter> <girng> So, passing a struct is by value, but the properties can be passed by referenced, or value as well
<FromGitter> <Blacksmoke16> i.e. cant access outside of that obj (except you can using a hack)
<FromGitter> <Blacksmoke16> `getter` just defines a method that does like
<absolutejam3> hm. Now I'm not sure if I tried it outside the instance. I'll have a look
<FromGitter> <Blacksmoke16> ```def foo ⏎ @foo ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5d1f962bb682244d498ae96e]
<FromGitter> <girng> So, when a struct is "passed by value", it's not 100% passed by value, it depends on its properties and if they are referenced or not, correct
<FromGitter> <naqvis> correct
<FromGitter> <Blacksmoke16> `property` defines both a getter and setter for the ivar
<absolutejam3> oh, okay
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f9698ccfbb80e41451dd8]
<FromGitter> <Blacksmoke16> (dont do this)
<FromGitter> <girng> wats that
<FromGitter> <Blacksmoke16> if you want to access an ivar, make a getter for it
<FromGitter> <girng> i don't like p.@ anyway don't worry lol
<FromGitter> <girng> looks funky
<FromGitter> <naqvis> @girng only types which are inherited from `Value` will be passed by value. ⏎ https://crystal-lang.org/api/0.29.0/Value.html ⏎ ⏎ Look at `StaticArray` [https://gitter.im/crystal-lang/crystal?at=5d1f96e907d71829adbb2003]
<FromGitter> <girng> u talking to absolutejam? sorry thought u meant me, cause u used Player lol
<FromGitter> <Blacksmoke16> i just copied your play to make it:P
<FromGitter> <Blacksmoke16> but, its a syntax that shouldn't be used (but is needed in stdlib i guess)
<FromGitter> <watzon> Has anyone here used svelte (https://github.com/sveltejs/svelte)?
<absolutejam3> fair enough. didn't know it was possible
<FromGitter> <Blacksmoke16> `getter foo` is the way to go
<FromGitter> <Blacksmoke16> if you want to be able to get it, but not set it
<FromGitter> <girng> @watzon i'm someone who hates virtual dom frameworks. so, seeing that makes me want to try it out, looks nice
<FromGitter> <watzon> It looks amazing. I just read the tutorial last night and it looks like a better Vue tbh
<FromGitter> <girng> here (https://i.gyazo.com/dd9a46338d0ff6b6ff6978b7bdc708b1.png) here is my beautiful OOP in action! πŸ˜†
<FromGitter> <Blacksmoke16> 😬
<FromGitter> <Blacksmoke16> could prob clean that up a good amount using guard clauses
lucasb has joined #crystal-lang
<FromGitter> <girng> wats dat
<FromGitter> <girng> πŸ˜†
<FromGitter> <watzon> @girng screenshot? Come on haha
<FromGitter> <watzon> Use hastebin or something
<FromGitter> <Blacksmoke16> so like instead of
<FromGitter> <girng> https://paste.ee/p/Digzy @watzon
<FromGitter> <Blacksmoke16> ```if zone = client.in_zone_obj ⏎ ... ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5d1f9c65ce3d0458f2b70f8a]
<FromGitter> <Blacksmoke16> you do
<FromGitter> <Blacksmoke16> ```return unless client.in_zone_obj```
<FromGitter> <girng> but i use zone methods
<FromGitter> <watzon> Holy cyclomatic complexity
<FromGitter> <Blacksmoke16> or instead of the `if distance_to(client.position, strongbox) < 100`
<FromGitter> <Blacksmoke16> do like
<FromGitter> <Blacksmoke16> `return client.send "Too far away!", "E" if distance_to(client.position, strongbox) >= 100`
<FromGitter> <tenebrousedge> `handle_interact` should probably be like `Player.open_box(box)`
<FromGitter> <Blacksmoke16> prob
<FromGitter> <Blacksmoke16> i like the comments tho
<FromGitter> <watzon> Me too, the comments are nice
<FromGitter> <watzon> Ameba would hate the amount of cyclomatic complexity there though
<FromGitter> <Blacksmoke16> @girng
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1f9dcfce3d0458f2b71bf0]
<FromGitter> <Blacksmoke16> FIXED
<FromGitter> <Blacksmoke16> vs triple nested `if` blocks
<FromGitter> <girng> @watzon some more https://paste.ee/p/rCN77, and https://paste.ee/p/81XDQ
<FromGitter> <Blacksmoke16> :cringe:
<FromGitter> <watzon> :supercringe:
<FromGitter> <watzon> Lol
<FromGitter> <girng> ?
<absolutejam3> what is `::Foo` in a class?
<absolutejam3> With no leading symbol name
<absolutejam3> Is that the current class?
<FromGitter> <Blacksmoke16> makes the type reference the type `Foo` outside the current namespace
<FromGitter> <watzon> Beat me to it
<FromGitter> <Blacksmoke16> i.e. if you have `Foo` defined in both top level and the current module
<FromGitter> <Blacksmoke16> and want to reference the top level one
<absolutejam3> ah
<FromGitter> <girng> @Blacksmoke16 where did you assign zone?
<FromGitter> <girng> that looks way nicer
<FromGitter> <Blacksmoke16> oh oops
<FromGitter> <girng> only reason i did the nested if blocks is
<FromGitter> <girng> cause i thought local variables
<FromGitter> <girng> have to be nested or w/e
<FromGitter> <Blacksmoke16> `return unless (zone = client.in_zone_obj)`
<FromGitter> <girng> if it's doing local variable =
<FromGitter> <Blacksmoke16> prob just do that
rohitpaulk has joined #crystal-lang
<FromGitter> <girng> wait what
<FromGitter> <girng> let me test that
<FromGitter> <Blacksmoke16> same way the strongbox one works
<FromGitter> <girng> HOW
<FromGitter> <girng> can that work
<FromGitter> <girng> if the local variable is NOT inside that block
<FromGitter> <Blacksmoke16> its defined in the conditional
<FromGitter> <watzon> Yup you can do assignments in conditionals
<FromGitter> <watzon> Very useful
<FromGitter> <watzon> `if foo = bar[:foo]?`
<FromGitter> <girng> could have sworn i was told that local variables / assignemtns can only be used
<FromGitter> <girng> inside that block
<FromGitter> <girng> it'sbeing assigned in
<FromGitter> <girng> how can it be assigned in 1 line above and still be used in the outer block
<FromGitter> <girng> 'wtf......
<FromGitter> <Blacksmoke16> i mean ofc you cant use the variable *above* that 1 line
<FromGitter> <Blacksmoke16> but if its not nil/false then its able to be used below it
<FromGitter> <girng> wow
<FromGitter> <Blacksmoke16> ( i mean it can be nil/false but in this case we're returning if it is)
<FromGitter> <girng> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fa0e8a0a38158f1aa3206]
<FromGitter> <girng> it works
<FromGitter> <Blacksmoke16> dont need the top return
<FromGitter> <Blacksmoke16> is the same as the one below it
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> guard clauses ftw
<FromGitter> <girng> what the hell
<FromGitter> <girng> inever knew that
<FromGitter> <girng> i thought the local variables had to be used inside their if else blocks
snsei__ has quit [Remote host closed the connection]
<FromGitter> <girng> if end*
<FromGitter> <girng> but it actually works
snsei__ has joined #crystal-lang
<FromGitter> <girng> this is gonna save a lot of lines, and increase readability tenfold
<FromGitter> <girng> @Blacksmoke16 ty
<FromGitter> <Blacksmoke16> np
<FromGitter> <girng> i hated the the nested ifs were getting anoying af lol
<FromGitter> <Blacksmoke16> `raise "Runes, Skills, or Misc items cannot be modified." if {"Skills", "Misc", "Runes", "Flasks"}.includes? main_on_item["type"]` would require big changes id imagine but this types of stuff is the perfect example of OOP + inheritance
<FromGitter> <Blacksmoke16> want an example?
snsei__ has quit [Remote host closed the connection]
snsei__ has joined #crystal-lang
snsei__ has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> i dont know enough to suggest the model of what everything would look like but the idea is
snsei__ has joined #crystal-lang
snsei__ has quit [Remote host closed the connection]
<FromGitter> <girng> iuno depends, everything wroks nicely i don't really want to change anything atm just gonna do these guard clauses tho
snsei__ has joined #crystal-lang
<FromGitter> <girng> cause that enhances readability a lot for me
<FromGitter> <Blacksmoke16> ofc, it would be a big rewrite
snsei__ has quit [Remote host closed the connection]
snsei__ has joined #crystal-lang
snsei__ has quit [Remote host closed the connection]
snsei__ has joined #crystal-lang
snsei__ has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> is the general idea
snsei__ has joined #crystal-lang
<FromGitter> <Blacksmoke16> or even a module like `include Editable` if the logic is the same for each type
<FromGitter> <Blacksmoke16> vs specific to each type
<FromGitter> <girng> ye
<FromGitter> <girng> true..
snsei__ has quit [Remote host closed the connection]
<FromGitter> <girng> i just dun want toswitch atm but maybe in future
<FromGitter> <girng> i'm on a roll atm
<FromGitter> <Blacksmoke16> save it for v2 at this point
<FromGitter> <girng> :D
<FromGitter> <girng> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fa3aa5e957c4d48db2419]
<FromGitter> <girng> DAMNNNN, so nice
<FromGitter> <Blacksmoke16> πŸ’―
<FromGitter> <girng> dude, the readability
<FromGitter> <Blacksmoke16> i think ideally this would be handled on a higher level tho
<FromGitter> <Blacksmoke16> vs having to do these same checks on each method
<FromGitter> <girng> true
<FromGitter> <girng> but yeah this is cool, TIL
<FromGitter> <girng> never knew crystal could get even better, and then boom
<FromGitter> <Blacksmoke16> coughnowgowritesometestscough
<FromGitter> <girng> πŸ˜†
<FromGitter> <Blacksmoke16> im telling you, once you start you'll like it
<FromGitter> <Blacksmoke16> but its a lot harder when you have monster methods like this if not impossible
<FromGitter> <Blacksmoke16> so prob not even easily doable anymore
laaron has quit [Remote host closed the connection]
<FromGitter> <girng> i'll try to write some later
<FromGitter> <girng> for like 1 method and just see how it goes
<FromGitter> <girng> one of the nasty methods
<FromGitter> <Blacksmoke16> ❀️ we're making progress
laaron has joined #crystal-lang
<FromGitter> <girng> i'm just thinking of so many ideas and coding, i'm on a roll. that's why i like about crystal, i can get my thoughts into code fast. but then again, that's why tests are probably there. to be there for the developer to catch stuff, a helping hand
<FromGitter> <Blacksmoke16> yes, so that you dont have to manually test as much when you make changes
teardown has joined #crystal-lang
<FromGitter> <Blacksmoke16> have a feeling its going to be hard to write tests just based on the design of how you structured the game
<FromGitter> <tenebrousedge> or to prove correctness. And tests are also documentation
<FromGitter> <Blacksmoke16> ☝️ July 5, 2019 1:38 PM (https://gitter.im/crystal-lang/crystal?at=5d1f8b2cdd0b530e40a37f3d)
<FromGitter> <Blacksmoke16> which would help as then you would be able to test smaller specific methods
<FromGitter> <Blacksmoke16> w/o having to have the full game running etc
<FromGitter> <girng> ;D
<FromGitter> <Blacksmoke16> but thats something that comes with experience
<FromGitter> <Blacksmoke16> hardest part imo in developing a good system is designing the architecture of it
<FromGitter> <tenebrousedge> yes
<FromGitter> <tenebrousedge> and on that note, @Blacksmoke16 can I ask you to take a look at something?
<FromGitter> <Blacksmoke16> sure
<FromGitter> <tenebrousedge> @Blacksmoke16 ignoring syntax errors https://play.crystal-lang.org/#/r/76sa
<FromGitter> <mwlang> @watzon Dude. Are you mind-melding me? I just stumbled upon https://svelte.dev/blog/write-less-code and was reading that a few minutes ago. Some really, *really* good ideas going on in this framework that's singing to me and my sense of less code, less bloat, higher performance, and, best of all, gigantic reduction of bandwidth to my end users.
<FromGitter> <Blacksmoke16> what about it @tenebrousedge ?
<FromGitter> <tenebrousedge> @Blacksmoke16 just want a sanity check on the general approach
<FromGitter> <mwlang> I'm going to see about injecting svelte into my new crystal project now and use that instead of vue.js
rohitpaulk has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> not really sure whats going on
<FromGitter> <tenebrousedge> @Blacksmoke16 scanf is a kind of DSL for extracting information from strings, basically the inverse of printf
<FromGitter> <tenebrousedge> ruby implementation https://github.com/ruby/scanf/blob/master/lib/scanf.rb
<FromGitter> <tenebrousedge> ruby docs https://apidock.com/ruby/Scanf
<FromGitter> <tenebrousedge> it's also a function in C/C++
<FromGitter> <Blacksmoke16> ah gotcha
<FromGitter> <tenebrousedge> so theoretically `"123 456".scanf("%d %d") #=> [123, 456]`
<FromGitter> <Blacksmoke16> neat
<FromGitter> <tenebrousedge> it's very useful, in certain situations
<FromGitter> <Blacksmoke16> any diff than like `"123 456".match(/(\d+) (\d+)/).try &.to_a`?
<FromGitter> <Blacksmoke16> `["123 456", "123", "456"]`
<FromGitter> <tenebrousedge> yes, it would return `Array(Int32)` not `Array(String)`
<FromGitter> <Blacksmoke16> oo ok
<FromGitter> <Blacksmoke16> neat
<FromGitter> <tenebrousedge> but I think that is sort of a sketch of how I want to approach this, maybe make the classes private
<FromGitter> <tenebrousedge> I will also want to support passing a block argument, but that doesn't seem too difficult
<FromGitter> <Blacksmoke16> sounds like a plan
<FromGitter> <tenebrousedge> but it would be nice to get just a sanity check on whether the classes make sense
snsei__ has joined #crystal-lang
<FromGitter> <Blacksmoke16> nothing comes to min
<FromGitter> <Blacksmoke16> but also not super familiar with it
<FromGitter> <tenebrousedge> well, as long as you're not screaming in horror, I'll take that as a plus
<FromGitter> <Blacksmoke16> whats your plan on doing the conversion?
<FromGitter> <tenebrousedge> I'm not entirely sure
<FromGitter> <Blacksmoke16> cant really use a case as that would make it a union
<FromGitter> <Blacksmoke16> bunch of overloaded methods called like `convert(val : String) : Int64` etc
<FromGitter> <tenebrousedge> :/ that sounds a little duplicative
<FromGitter> <tenebrousedge> hmm, I'll bookmark that
<FromGitter> <Blacksmoke16> is basically what athena does with route/query params
<FromGitter> <Blacksmoke16> for primitive types, complex ones require a converter to specify the logic of what should happen
<FromGitter> <tenebrousedge> `scanf` only handles strings, numbers, and pointers
<FromGitter> <Blacksmoke16> well there you go, is all you need then
<FromGitter> <Blacksmoke16> how would a pointer work?
<FromGitter> <tenebrousedge> I dunno. It seems like a bad idea
<FromGitter> <tenebrousedge> but Crystal should support anything that C/C++ supports
<FromGitter> <watzon> Not necessarily
<FromGitter> <tenebrousedge> o.o?
<FromGitter> <asterite> I tried to implement scanf once, I can't remember how I did it
<FromGitter> <asterite> but it has to be safe...
<FromGitter> <asterite> the problem with scanf is that it receives references to variables which have to have a type, so it's kind of opposite to how you program in crystal, where the types are inferred
<FromGitter> <asterite> I guess one way would be to do something like `"an int between single quotes: '%'".scanf(Int32)`
<FromGitter> <asterite> then each `%` is matched against the given type, and each type would have to implement a way to consume input
<FromGitter> <asterite> then scanf becomes extensible, you could parse `"point: %".scanf(Point)` and `Point` could parse stuff like "x, y"
<FromGitter> <asterite> but scanf in Ruby is not used a lot for some reason... I think regex has a simpler interface, even though it's slower
<FromGitter> <watzon> I feel like thats the main reason, speed
<FromGitter> <watzon> With ruby you need any performance increase yo ucan get
<FromGitter> <asterite> Yes, but scanf in Ruby is actually slower than using a regex
<FromGitter> <asterite> https://carc.in/#/r/76sh
<FromGitter> <watzon> Oh is it?
<FromGitter> <watzon> Then who knows
<FromGitter> <asterite> The thing is that a regex might be compiled, while with scanf the pattern has to be parsed over and over... though I'm not sure that's the reason it's slower
<FromGitter> <asterite> then regex is way more flexible, you can specify exactly how to parse a word, or a number
snsei__ has quit [Ping timeout: 276 seconds]
<FromGitter> <girng> interesting
<FromGitter> <Blacksmoke16> @mwlang angular isnt far off from that num of chars
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fb6c0dd0b530e40a4b855]
<FromGitter> <Blacksmoke16> nvm, more char wise than i thought
<FromGitter> <watzon> The biggest benefit to svelite is the end product
<FromGitter> <watzon> You end up with a much smaller and faster
<FromGitter> <Blacksmoke16> true
<FromGitter> <watzon> I'm playing around with it right now
<FromGitter> <Blacksmoke16> does it handle routing? or is it just templating?
<FromGitter> <watzon> It's got some gotchas. Definitely nowhere near as refined as Vue or Angular
<FromGitter> <watzon> Svelte itself doesn't
<FromGitter> <watzon> But it has a big brother `sapper` that does
<FromGitter> <Blacksmoke16> gotcha
<FromGitter> <Fryguy> I happened to look up Crystal on Wikipedia today, and noticed it was nominated for deletion for some reason - https://en.wikipedia.org/wiki/Crystal_(programming_language)
<FromGitter> <Fryguy> I can't understand *why* though
<FromGitter> <Blacksmoke16> `Topic has not received significant coverage in reliable sources that are independent of the subject, so it fails GNG Charmk (talk) 19:10, 5 July 2019 (UTC)`
<FromGitter> <Fryguy> yeah, I'm also seeing Nim with the same rationaly
<FromGitter> <Blacksmoke16> rip
<FromGitter> <Blacksmoke16> https://pragprog.com/book/crystal/programming-crystal should suffice
<FromGitter> <Fryguy> oh good call
absolutejam4 has joined #crystal-lang
<FromGitter> <Blacksmoke16> dunno how to comment that ho
absolutejam3 has quit [Ping timeout: 272 seconds]
snsei__ has joined #crystal-lang
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter> <watzon> Ok this is kinda beautiful ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fcad877c54c13e607ff04]
<FromGitter> <watzon> svelte has a spread operator for component props
<FromGitter> <girng> i added that tcp echo code lol
<FromGitter> <girng> glad it's still there ;P
<FromGitter> <girng> > received significant coverage in reliable sources that are independent of the subject
<FromGitter> <girng> github isn't a reliable source?
<FromGitter> <mwlang> has anybody parked a crystal web server app behind phusion passenger?
<FromGitter> <mwlang> I'm trying to work out how to deploy and host a crystal app in the cloud.
<FromGitter> <Blacksmoke16> nginx?
<FromGitter> <Blacksmoke16> would be the easiest imo
<FromGitter> <Blacksmoke16> nginx + docker
<FromGitter> <mwlang> got a set up guide for nginx + crystal?
<FromGitter> <mwlang> been futzing with docker for 3 hours now...giving up and going with what I know best.
<FromGitter> <watzon> I'm using Caddy with transparent proxies and git deployment
snsei__ has quit [Ping timeout: 252 seconds]
<FromGitter> <Blacksmoke16> something like that
<FromGitter> <Blacksmoke16> where docker is running the api container on that port
<FromGitter> <mwlang> so just proxy passing
<FromGitter> <Blacksmoke16> yea
<FromGitter> <mwlang> what I really am lacking is running the crystal app.
<FromGitter> <mwlang> in my case, lucky framework
<FromGitter> <Blacksmoke16> what were you doing with your docker/
<FromGitter> <mwlang> trying to get it to run... :-p
<FromGitter> <mwlang> locally in docker that is.
<FromGitter> <mwlang> I'm not all that experienced with docker.
<FromGitter> <Blacksmoke16> whats the error?
<FromGitter> <mwlang> capturing error now and will add to that gist.
<FromGitter> <mwlang> Actually, I forgot...I got it to build and "run" -- it just doesn't respond on the port.
<FromGitter> <Blacksmoke16> whats the output of `docker ps`
<FromGitter> <mwlang> gist updated.
<FromGitter> <mwlang> maestro_db_1 is postgres and maestro_web_1 is the crystal app.
<FromGitter> <mwlang> redis is another project not used here.
<FromGitter> <Blacksmoke16> and it just doesnt respond to requests?
<FromGitter> <mwlang> nope.
<FromGitter> <mwlang> should respond to http://localhost:5000/ right?
<FromGitter> <Blacksmoke16> assuming you have some action that responds to that yea
<FromGitter> <mwlang> it works outside docker locally
<FromGitter> <mwlang> I just noticed... docker ps shows that the web container is running "/sbin/my_init"
<FromGitter> <mwlang> shouldn't that be "lucky dev" ?
<FromGitter> <Blacksmoke16> the command in the dockerfile should override that of the image yea
<FromGitter> <mwlang> hmmm...backing some of the edits up. This was something I was seeing earlier and have no idea where it's coming from: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fd20511bfea0b67aea6df]
<FromGitter> <Blacksmoke16> thats prob the issue
<FromGitter> <mwlang> ok, found the /sbin/my_init and changed that.
<FromGitter> <Blacksmoke16> granted your dockerfile is much more complex than mine...
<FromGitter> <mwlang> I'll take a simpler one if you want to share it.
<FromGitter> <Blacksmoke16> but not sure there is a way around it since you have to install more stuff
<FromGitter> <mwlang> ok, I'm getting somewhere.
<FromGitter> <mwlang> Cannot start service web: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"lucky\": executable file not found in $PATH": unknown
<FromGitter> <mwlang> so now...get shards installed or get the right path to lucky configured...
<FromGitter> <Blacksmoke16> should just have to change your command to maybe like `./bin/lucky watch`
<FromGitter> <Blacksmoke16> assuming your work dir is the root
<FromGitter> <mwlang> actually, I don't think it's installing crystal...working on that now.
<FromGitter> <Blacksmoke16> should already be installed if you use the crystal docker image
<FromGitter> <mwlang> stealing docker files from amber project.
<FromGitter> <mwlang> I wasn't using crystallang image just then...now am.
<FromGitter> <Blacksmoke16> that would do it
<FromGitter> <mwlang> gone through a bunch of iterations.
<FromGitter> <mwlang> just trying stuff...but now trying to do it a bit more constructively.
absolutejam4 has quit [Ping timeout: 268 seconds]
<FromGitter> <mwlang> how do I just not run a command and bring up image so I can launch a bash shell?
<FromGitter> <mwlang> I need to go hunt for where `lucky` gets installed when shards install runs.
<FromGitter> <Blacksmoke16> if the container is already running you can do like
<FromGitter> <Blacksmoke16> `docker exec -it web_1 bash`
<FromGitter> <Blacksmoke16> which puts you into the container in a bash shell
<FromGitter> <mwlang> yeah, figured it out and made a good deal more progress.
<FromGitter> <Blacksmoke16> \o/
<FromGitter> <mwlang> new problem is the app is attempting to start before the dbms is ready
<FromGitter> <mwlang> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d1fe0ed076ffa65b0567b05]
<FromGitter> <Blacksmoke16> the `app_1`?
<FromGitter> <mwlang> yes
<FromGitter> <Blacksmoke16> `"exec format error"` might be the bigger issue
<FromGitter> <Blacksmoke16> i remember seeing that when trying to run a container built for a diff arch
<FromGitter> <Blacksmoke16> like amd64 on arm
<FromGitter> <mwlang> well, I logged in and what I saw was failure to connect to db
<FromGitter> <Blacksmoke16> try starting them separately
<FromGitter> <Blacksmoke16> like `docker-compose up -d app_1
<FromGitter> <mwlang> ok
<FromGitter> <Blacksmoke16> er db first
<FromGitter> <mwlang> Unhandled exception: (DB::ConnectionRefused)
<FromGitter> <mwlang> actually, I'm not sure how to expose the dbms in one docker image to the other image if I'm running separately in command line
<FromGitter> <Blacksmoke16> whats the db url its trying to connect to
<FromGitter> <mwlang> instead of docker-compose up
<FromGitter> <Blacksmoke16> well `docker-compose up -d db_1` is still using your compose file
<FromGitter> <Blacksmoke16> so the url/details are prob wrong
<FromGitter> <mwlang> oh, let me fire 'em up that way.
<FromGitter> <Blacksmoke16> should just have to reference the service name in the connection url
<FromGitter> <mwlang> I was just using docker run
<FromGitter> <Blacksmoke16> ah
<FromGitter> <mwlang> can that docker-compose command be modified to display output as it starts up?
<FromGitter> <Blacksmoke16> would need two terminals
<FromGitter> <mwlang> I just get green "done" on both images.
<FromGitter> <Blacksmoke16> just remove the `-d`
<FromGitter> <Blacksmoke16> `-d` makes them run in the background with attaching the the output
<FromGitter> <mwlang> ah
<FromGitter> <mwlang> good to know
<FromGitter> <Blacksmoke16> without*
<FromGitter> <mwlang> ok, so the app doesn't launch...same "exec format error"
<FromGitter> <Blacksmoke16> you have intel cpu?
<FromGitter> <Blacksmoke16> er one that is amd64?
<FromGitter> <mwlang> Intel