ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Crystal 0.21.1 | Fund Crystal's development: | Paste > 3 lines of text to | GH: | Docs: | API: | Logs:
marciogm has quit [Ping timeout: 268 seconds]
marciogm has joined #crystal-lang
<FromGitter> <fridgerator> I believe @sdogruyol built it from an experimental crystal branch
<FromGitter> <fridgerator> You can do it manually though right now with 'Process.fork'
<FromGitter> <fridgerator> If your kernel supports SO_REUSEPORT, check a code example here
_whitelogger has joined #crystal-lang
DaleK5whr has joined #crystal-lang
DaleK5whr has quit [Client Quit]
pduncan has quit [Ping timeout: 246 seconds]
pduncan has joined #crystal-lang
snsei has joined #crystal-lang
snsei has quit [Client Quit]
snsei has joined #crystal-lang
<FromGitter> <elorest> @fridgerator thanks.
snsei has quit [Remote host closed the connection]
<FromGitter> <raydf> Hello everyone
<FromGitter> <raydf> how can i restrict a union type with a case statement, tried: ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <domgetter> This is a compiler error I got on a line of commented out code:
<FromGitter> <domgetter> Is that a bug?
pabs has joined #crystal-lang
jaitaiwan_ has joined #crystal-lang
shelvac2 has joined #crystal-lang
swav_ has joined #crystal-lang
danielpclark has quit [*.net *.split]
kodo[m] has quit [*.net *.split]
dzv has quit [*.net *.split]
jaitaiwan has quit [*.net *.split]
pabs_ has quit [*.net *.split]
onionhammer has quit [*.net *.split]
shelvacu has quit [*.net *.split]
swav has quit [*.net *.split]
g3funk has quit [*.net *.split]
lhz has quit [*.net *.split]
swav_ is now known as swav
braidn_ has joined #crystal-lang
snsei has joined #crystal-lang
lhz has joined #crystal-lang
danielpclark has joined #crystal-lang
dzv has joined #crystal-lang
onionhammer has joined #crystal-lang
kodo[m] has joined #crystal-lang
snsei has quit [Ping timeout: 260 seconds]
olek_poz has joined #crystal-lang
madgoat has joined #crystal-lang
madgoat has left #crystal-lang [#crystal-lang]
<FromGitter> <crisward> @raydf This you need to us `.is_a?(String)` etc.
<FromGitter> <crisward> or possibly typeof(column_value) / column_value.class
<FromGitter> <crisward> ```code paste, see link``` []
snsei has joined #crystal-lang
snsei has quit [Ping timeout: 260 seconds]
Papierkorb has quit [Ping timeout: 264 seconds]
mark_66 has joined #crystal-lang
olek_poz has quit [Ping timeout: 260 seconds]
<FromGitter> <sdogruyol> @elorest i compiled Crystal with multithread support :)
Qchmqs has joined #crystal-lang
Raimondii has joined #crystal-lang
Raimondi has quit [Ping timeout: 268 seconds]
Raimondii is now known as Raimondi
olek_poz has joined #crystal-lang
gloscombe has joined #crystal-lang
<crystal-gh> [crystal] ysbaddaden opened pull request #4234: Fix: OpenSSL 1.1.0 changed context options (master...std-fix-openssl-110)
Papierkorb has joined #crystal-lang
<FromGitter> <bew> @domgetter I think yes
Kug3lis has joined #crystal-lang
snsei has joined #crystal-lang
Kug3lis is now known as Kug3lis_off
Kug3lis_off is now known as Kug3lis
Kug3lis has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
snsei has quit [Ping timeout: 268 seconds]
Kug3lis has joined #crystal-lang
Kug3lis has quit [Quit: Textual IRC Client:]
bjz has joined #crystal-lang
<crystal-gh> [crystal] ysbaddaden pushed 1 new commit to master:
<crystal-gh> crystal/master 3119e59 Julien Portalier: Fix: OpenSSL 1.1.0 changed context options...
fryguy9 has joined #crystal-lang
scottj has joined #crystal-lang
<travis-ci> crystal-lang/crystal#3119e59 (master - Fix: OpenSSL 1.1.0 changed context options): The build passed.
<crystal-gh> [crystal] ysbaddaden opened pull request #4236: Configurable DNS resolvers (master...std-addrinfos-dns-resolvers)
bjz_ has joined #crystal-lang
bjz has quit [Ping timeout: 260 seconds]
fryguy9 has quit [Quit: Leaving.]
fryguy9 has joined #crystal-lang
bjz has joined #crystal-lang
bjz_ has quit [Ping timeout: 240 seconds]
Qchmqs has quit [Ping timeout: 240 seconds]
Qchmqs has joined #crystal-lang
fryguy9 has quit [Quit: Leaving.]
fryguy9 has joined #crystal-lang
sz0 has joined #crystal-lang
Qchmqs has quit [Ping timeout: 260 seconds]
Qchmqs has joined #crystal-lang
olek_poz has quit [Ping timeout: 260 seconds]
fryguy9 has quit [Quit: Leaving.]
fryguy9 has joined #crystal-lang
fryguy9 has quit [Quit: Leaving.]
bjz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
snsei has joined #crystal-lang
mark_66 has quit [Remote host closed the connection]
snsei has quit [Ping timeout: 260 seconds]
<FromGitter> <raydf> Thanks @crisward, i solved the problem with the case statement, in reality the code i uploaded is valid but the compiler was giving me another error related to will-pg PG::Numeric type when converting to JSON::Any.
<crystal-gh> [crystal] mverzilli opened pull request #4237: Skip macro method (master...feature/skip_file)
fryguy9 has joined #crystal-lang
fryguy9 has quit [Quit: Leaving.]
fryguy9 has joined #crystal-lang
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
fryguy9 has quit [Quit: Leaving.]
fryguy9 has joined #crystal-lang
olek_poz has joined #crystal-lang
snsei has quit [Ping timeout: 264 seconds]
<jokke> hi
<jokke> does HTTP::Server allow persistent connections?
<jokke> i just checked tcpdump on the port my test server was listening on and even though my client (a ruby app) uses HTTPClient which reuses connections i saw packets from a lot of different ports
<jokke> this wasn't the case when i used a ruby rack server
<jokke> building crystal from git now to test if the reuse_port arg makes a different
<jokke> *difference
scottj has quit [Quit: leaving]
<RX14> jokke, reuse_port doesn't have an effect on reusing TCP connections, or are you talking about differwent things
<jokke> ah
<jokke> okay
<RX14> crystal should handle Connection: Keep-Alive
<jokke> RX14: hmm
<jokke> weird
<Yxhuvud> reuse port is for using the same socket for multiple threads, no?
<jokke> this should reuse connections by default?
<RX14> multiple processes
<RX14> multiple threads could just use the same FD
<Yxhuvud> ah yes, that is what I meant :P
<RX14> reuseport allows multiple processes to accept connections
<RX14> and connections are loadbalanced in the kernel
<RX14> which is super nice
<jokke> whoa
<jokke> that indeed sounds nice
<RX14> yeah
<jokke> i didn't even know that that's possible
<RX14> I got about 500k requests per second with it on about 7 cores
<jokke> niiiiice
<RX14> the other 3 were for wrk
<RX14> i'm planning to have another go with 2 VMs
<RX14> because scaleway has 2.5gbps interconnects between VMs
<RX14> i should be able to test that really well
<RX14> as it was approaching 1gbps on the loopback interface
<jokke> woah cool. I'm interested in the results
<RX14> it's... somewhere on my todo list
<jokke> :)
<jokke> are you still using crouter btw?
<RX14> no
<jokke> k
<jokke> kemal?
<RX14> i have my own "private" framework now
<jokke> hehe
<jokke> why private
<RX14> it's in flux so it's just part of the app
<jokke> sharing is caring!
<RX14> i'll open source it once it's sort of mature
<jokke> ok cool
<RX14> i'll probably cut out the git tree to get the history of it too
<jokke> does it have the same idea as crouter (as in just being a router)
<RX14> because the framework is evolving alongside another application
<RX14> and lives in it's folder under that to allow quick development
<jokke> i see
<RX14> jokke, no, it's much more complete
<jokke> hmmmm
<jokke> too bad
<RX14> it can be quite lightweight
<jokke> mmh
<RX14> by default it is
<jokke> i'd still much rather have a plain ol' router
<RX14> the router is so small anyway
<RX14> because it's built on the radix shard
<RX14> like kemal
<jokke> which could be a part of a bigger framework of course
<RX14> using radix shard as a router is like 10 lines of code
<RX14> so it's honestly not worth being it's own thing
<jokke> oh ok
fryguy9 has quit [Quit: Leaving.]
<jokke> would have to look in to that
fryguy9 has joined #crystal-lang
Qchmqs has quit [Ping timeout: 256 seconds]
<RX14> jokke, this is what it looks like
<RX14> this is the entirety of the web framework code:
<jokke> RX14: cool
<RX14> pretty much the entire scope of expansion on the framework is in the utilities it provides
<jokke> RX14: i don't quite understand why tcpdump shows so many different ports when running against the crystal server
<jokke> i checked, that keep-alive is set
<RX14> well, is keep-alive working?
<jokke> well, apparently not
<RX14> add a puts to the client's TCP connect() call
<jokke> but it is with webrick for example
<jokke> the client is ruby
<jokke> HTTPClient
<RX14> I assume it's in C
<RX14> great
<RX14> that's something I want to achieve with crane, being able to jump into the stdlib and compiler almost seamlessly with an editor and change and debug stuff
<jokke> mmh
<RX14> fluidity of debugging and modifications across projects is something i'd love with shards/crane
<jokke> but i kind of doubt that it's a client problem since it worked with a webrick/thin
<RX14> yeah...
<jokke> also if i spawn 10k clients and hammer the server the server tells me too many open files
<jokke> hm
<RX14> i think I know why...
<jokke> but that might be alright
<jokke> 10k open files might be too much
<jokke> oh no
<jokke> it should be one socket
<jokke> since HTTPClient _should_ do connection pooling
<RX14> yeah I know why it's failing
<jokke> you do?
<RX14> yeah
<jokke> weeeell?
Yxhuvud has quit [Read error: Connection reset by peer]
<jokke> please enlighten me :)
<RX14> i have no idea why the specs don't fail though
<jokke> oh really a crystal problem?
<RX14> obviously lol
<jokke> i always assume i'm doing something wrong first ;)
<RX14> it's the most likely thing to be broken
Yxhuvud has joined #crystal-lang
<RX14> it closes the request body after each request to try and read the entire request
<RX14> but the content class implementations (these wrap the body) call super here:
<FromGitter> <chuckremes> Question: is `spawn` an alias for ``?
<RX14> eyy jokke
<RX14> it was me!
<jokke> jah?
<jokke> RX14: lol :)
<FromGitter> <chuckremes> Nevermind… found it in the source. It looks like `spawn` calls `` internally and also enqueues the newly generated fiber onto the scheduler queue.
<RX14> yup
<RX14> don't use Fiber yourself
<RX14> it's got loads of gotchas and is an internal class
<FromGitter> <chuckremes> But I should be able to use `Fiber.yield` and `Fiber.resume`, yes?
<FromGitter> <chuckremes> I ask because I want to spike out a proof-of-concept `celluloid`-style library for crystal as a learning exercise.
<FromGitter> <chuckremes> I just want to make simple `Futures`.
<RX14> crystal already has futures
<RX14> they're just not well advertised and actually will probably be redone
<FromGitter> <chuckremes> Okay, I’m not privy to the secret classes. I’m looking at the online docs and the gitbook. Neither mentions futures or anything similar.
<RX14> it's because it's like spawn
<RX14> a top-level method
<FromGitter> <chuckremes> ah...
<RX14> oops
<RX14> wrong link
<FromGitter> <chuckremes> presumably the “toplevel” names are the equivalent of Ruby’s `Kernel` namespace?
<RX14> i would guess so?
<RX14> i havent used ruby for...
<RX14> years
<FromGitter> <chuckremes> Well, I’m very new to crystal… just a few days. I like what I see so far.
<RX14> a celuloid-style lib would be interesting to see
<RX14> i'm not quite sure what celluloid brings to crystal
<FromGitter> <chuckremes> I need to experiment to see if there is enough metaprogramming capability to pull it off.
<RX14> i'd hazard a guess and say yes
<RX14> and i'd be 90% sure there is
<RX14> DCell would be the most interesting one to replicate
<FromGitter> <chuckremes> I have no intention of porting all of celluloid. However, I do think it’s useful to have objects that proxy access to an actor or future. Celluloid brings nice syntax to it.
<RX14> Celluloid::IO is obviated by evented IO in the stdlib
<FromGitter> <chuckremes> Ah yes, well this would be an early experiment to verify that working on DCell or ECell is worthwhile.
<RX14> yeah there have been talks of actor frameworks before
<RX14> and we've generally agreed that it'd be nice for someone to take a stab at it
<RX14> but nobody had the time atr the time
<FromGitter> <chuckremes> haha, I bet.
<FromGitter> <chuckremes> while exposing fibers and schedulers is nice for the implementer, most programmers don’t want to have to juggle fibers, channels, and all of the other primitives. A slightly higher-level lib is useful in that regard.
<FromGitter> <chuckremes> gonna work on this today
<RX14> well, fibers and channels really aren't all that primitive
<RX14> they're surprisingly easy to use in most situations
fryguy9 has quit [Quit: Leaving.]
<FromGitter> <chuckremes> sure, but they are an implementation detail. They should be tucked away where they can’t be seen (for most code).
<FromGitter> <chuckremes> that’s IMO, of course.
<RX14> not at all
<FromGitter> <sdogruyol> They are simple enough
<FromGitter> <sdogruyol> Just like go
<RX14> they're high-level constructs that people use all the time to build applications
<RX14> you can go higher level but fibers and channels are really not hard or need a lot of boilerplate to use
<RX14> actors and futures would complement them
<FromGitter> <chuckremes> All right… don’t want to argue. IMO, I prefer to not use fibers & channels directly. I want my objects to run things asynchronously for me and return the results when I ask for it. I like straight up, no frills imperative programming. But I’m old fashioned.
<RX14> buffered fibers are essentially queues...
<RX14> the future wrapper makes code smaller in a few usecases
<RX14> but I find mysel almost never using them actually
<RX14> you might not want to argue but it's a fact that the concurrency boilerplate for using raw channels and fibers is almost non-existant in most cases
<FromGitter> <chuckremes> Sure, but I don’t want to see it AT ALL.
<RX14> but you have to replace it with something
<RX14> and if that something is essentially the same or offers little to no improvement why use it?
<RX14> thats what i'm saying
<RX14> you can have a go but "I don't want to see it" is just closing your mind
<RX14> finding a better solution starts with understanding the current one
<RX14> and it seems to be that you don't
<FromGitter> <chuckremes> I don’t understand you. Why so argumentative?
<FromGitter> <chuckremes> And no need to be insulting either.
<RX14> because I want to help you, and dismissing fibers and channels as "primitives to be hidden away" in't a good starting point
<FromGitter> <chuckremes> I haven’t dismissed anything.
<FromGitter> <chuckremes> I, meaning ME, don’t want to see the concurrency “gears” at work. I want a library to do it for me.
<RX14> i didn't mean to sound insulting, sorry
<FromGitter> <chuckremes> And I’ll write that library (or try to spike one)
<FromGitter> <chuckremes> Ok
<FromGitter> <chuckremes> Listen, I’m not trying to impose my view of the world on crystal.
<RX14> but what i'm trying to say is that they're not gears
<FromGitter> <chuckremes> I want to learn about it and spike a project or two to get to know it better.
<RX14> and that just like go, most programs will use fibers and channels directly instead of delegating to a library
<FromGitter> <chuckremes> I fwhat I create is useful, then great. If not, it will sink like a million other hobby projects.
<FromGitter> <chuckremes> That’s cool. It isn’t a style that I like. Doesn’t make it wrong or right… it just is how I like it.
<FromGitter> <chuckremes> Ok, we’ve taken enough time on this topic. I’ll be back with questions later.
<FromGitter> <chuckremes> Thanks for your pointers so far. Very helpful.
<RX14> no problem
<RX14> creating a library is a good way to learn about fibers and channels
fryguy9 has joined #crystal-lang
<jokke> RX14: sorry, had to run. Sure it's the commit?
<RX14> jokke, i'm not sure at all
<jokke> hm
<jokke> i can try finding out
<RX14> bisect from 0.17.0
<jokke> yeah
<jokke> but building takes ages :P
<RX14> you don't been to build
<RX14> it's a stdlib change
<RX14> well you need to build
<RX14> actually you do need to build the compiler
<RX14> damn
<jokke> yay
<RX14> but not for every revision
<jokke> i'll try checking out the parent commit
<RX14> and actually not if you use crenv
<RX14> because you just need to do this
<RX14> checkout commit, find latest tag, install that crystal version, compile test executable, run tests
<RX14> if you can automate that in a bash script you can bisect super fast
<jokke> mhm worth a try
<RX14> plus, compiling the compiler takes 37s
<jokke> yah
<RX14> but as you narrown down into the exact crystal version the regression happened in
<RX14> you don't need to recompile
<RX14> because it's only a stdlib change
fryguy9 has quit [Quit: Leaving.]
<BlaXpirit> also time should not be a worry because you can just leave it running?
<crystal-gh> [crystal] mverzilli closed pull request #4237: Skip macro method (master...feature/skip_file)
<RX14> BlaXpirit, but that assumes you can be bothred to automate it
<BlaXpirit> at this point someone should publish a script to do that
<RX14> yup
<RX14> it would also prompt for tweaths to the test script if it fails to compile
<BlaXpirit> so crenv can install any crystal version, huh?
<RX14> trying both in the intervening period
<RX14> BlaXpirit, yes
<BlaXpirit> i don't understand what you mean by "tweaths"
<RX14> tweaks
<RX14> i'm just bad at typing
<FromGitter> <domgetter> RX14: Is that why you get the compiler to do it for you?
<RX14> hmm?
<FromGitter> <domgetter> It was a joke about type inference and how you're "bad at typing"
<RX14> oh
<RX14> lol
<jokke> RX14: not your commit it seems
<RX14> oh?
<RX14> thats a surprise
pduncan has quit [Ping timeout: 256 seconds]
<jokke> or not crystals fault
<RX14> was it broken on 0.17.0 too?
<jokke> yup
<RX14> i guess it must never have worked then...
<jokke> or that
<RX14> maybe try another client
<jokke> mhm
<RX14> it might just be an interaction bug
<RX14> no real bug per se
<RX14> but just these two clients are lightly off
<RX14> slightly*
<jokke> yeah not working even in 0.10
<RX14> i blame a broken crystal implementation with dodgy specs
<jokke> hm
<jokke> RX14: does HTTP::Client do keepalive?
<RX14> crystal's?
<jokke> never mind
<jokke> rtfm
<RX14> it does if you
<jokke> yup
<RX14> but I wouldn't do that
<jokke> why?
<RX14> i just like to use known-good implementations
<RX14> and if HTTP::Server is wrong why not HTTP::Client
<jokke> mmh
<RX14> it could be a bad interpretation of the spec where crystal works with crystal but nothing else
<RX14> try this
<jokke> right
<RX14> something like
<RX14> actually no
<RX14> i can't find a good way to repeat strings in bash
<RX14> shame
<jokke> xargs?
<RX14> would xargs help?
<jokke> well depending on what you want to do
<jokke> abyways
<FromGitter> <drosehn> repeat strings in what sense?
<jokke> *anyways
<jokke> it's definately crystal
<jokke> different port every time
<RX14> don't check the port
<jokke> why?
<RX14> curl -v will tell you whether it reconencted or not
<jokke> oh
<jokke> ok
<RX14> * Connection #0 to host left intact
<RX14> * Found bundle for host 0x137f730 [can pipeline]
<RX14> * Connected to ( port 443 (#0)
<RX14> * Re-using existing connection! (#0) with host
<jokke> * Re-using existing connection! (#0) with host localhost
<jokke> ok
<RX14> huh...
<jokke> so not an issue there
<RX14> thats weird
<jokke> weird that tcpdump shows different ports each time
<RX14> yeah...
<RX14> that doesn't make sense
<jokke> yeah
<jokke> maybe some kernel-internal multiplexing shizzle
<RX14> i don't think so...
<RX14> well in tcpdump you should be able to see whether a new TCP connection was made
<RX14> it should show TCP handshakes
<jokke> waaah never mind
<FromGitter> <drosehn> repeating strings in bash: `STR=. CNT=0 ; while test $CNT -lt 10 ; do printf "%s" "$STR"; CNT=$((CNT+1)) ; done ; printf "\n"`
<jokke> the line broke and i misread
<jokke> it's the same source port
<jokke> so it's ruby
<jokke> not crystal
<jokke> and not curl :)
<RX14> jokke, but...
<jokke> hm?
<RX14> ruby works with a ruby server right
<RX14> or what?
<jokke> yeah that's the weird part
<jokke> lol ok
<RX14> so something is still broken
<jokke> ah jeez fucking linebreaks
gloscombe has quit [Remote host closed the connection]
* jhass steals all of jokke's linebreaks
<jhass> there, tell me if it's better now
<jokke> i should mention that i'm using HTTPClient in combination with Celluloid
<jokke> which is a scary combo
<jhass> ah good old messy celluloid
<jokke> but i need to find out if the combo is in fact able to reuse connections
<jhass> what if the answer is no?
<jokke> jhass: then we have to drop ruby
<jhass> are you searching for something that is able to do a lot of requests?
<jokke> and use something shitty like node
<jhass> typhoeus surely does reuse connections
<jokke> jhass: background: we have a tcp server that's maintaining a few thousand seperate tcp connections, receives some data from them and forwards them to a rest api. It would be very bad if we would have to spawn a new socket for each http request to the api since it's https
<jokke> celluloid would be nice since we could spawn one actor per tcp connection
fryguy9 has joined #crystal-lang
<jhass> mh, so you want to reuse + multiple connections to the same origin nonetheless I guess
<jokke> but all actors should reuse the same http(s) connection to the rest api
<FromGitter> <domgetter> Is monkeypatching as "frowned upon" here as it is in Rubyland?
<jhass> same levels I'd say, you should have a strong reason but if you can provide it it's totally fine
<FromGitter> <domgetter> jhass: thanks, Ill pull these out into library calls then
fryguy9 has quit [Client Quit]
<jhass> I like to stub out missing stdlib features while working a project and then working on upstreaming them once I know they're what I need
<FromGitter> <jwoertink> I get a syntax error from this bit
<FromGitter> <jwoertink> is this something that should be reported? or am I doing something weird here?
<RX14> you're doing something very weird
<FromGitter> <jwoertink> lol
<jhass> a type parameter can't be a runtime value
<RX14> ^
<RX14> the parser expects only constants or identifiers in generic args
<RX14> you can't use a staticarray here
<RX14> use a normal Array
<jokke> jhass: hm okay weird
<jokke> it seems it's not celluloid either
<FromGitter> <jwoertink> ok, cool
<FromGitter> <domgetter> Why do the docs make it look like it's okay?
<jokke> doesn't work with ruby threads either
<RX14> @domgetter they don't?
<FromGitter> <domgetter> I'm seeing StaticArray(TypeName, some_value)
<FromGitter> <domgetter> isn't that what jwoertink did?
<jokke> jhass: have you used HTTPClient?
<jhass> no
<RX14> @domgetter not at all
<jokke> ok
fryguy9 has joined #crystal-lang
<FromGitter> <jwoertink> Yeah, it makes sense that it needs to be a static type, and not a variable
<RX14> @domgetter jwoertink used a variable, in the docs it's a constant
<FromGitter> <jwoertink> just weird that it throws syntax error instead of some other "Hey, you're doing something weird" error
<FromGitter> <domgetter> got it
<jhass> that you can actually open an issue about if you want to see it improved
<FromGitter> <jwoertink> I'll do that. I spent way too long looking at the actual syntax for that
<jhass> nicer error messages totally is in scope ;)
fryguy9 has quit [Client Quit]
fryguy9 has joined #crystal-lang
fryguy9 has quit [Client Quit]
fryguy9 has joined #crystal-lang
fryguy9 has quit [Client Quit]
fryguy9 has joined #crystal-lang
<travis-ci> crystal-lang/crystal#c01a6c7 (master - Skip macro method (#4237)): The build has errored.
fryguy9 has quit [Client Quit]
fryguy9 has joined #crystal-lang
fryguy9 has quit [Quit: Leaving.]
<FromGitter> <domgetter> woot, Just got my templating engine adaptable to Kilt :)
<FromGitter> <domgetter> Feel free to check it out:
<FromGitter> <zatherz> I'm currently struggling with the proper architecture for a chat bot
<FromGitter> <zatherz> I want the ability to have plugins
<FromGitter> <zatherz> that you just put in a `plugins/` directory
<FromGitter> <zatherz> and when rebuilding, they're built into the bot and you can access all the main Bot class fields
<FromGitter> <zatherz> at the same time, I want to have the ability for plugins to depend on other plugins
<FromGitter> <zatherz> right now I have to use workarounds such as ⏎ ⏎ ```core_plugin = bot.plugins[CorePlugin] ⏎ ⏎ if core_plugin.is_a? CorePlugin ⏎ end``` []
<FromGitter> <zatherz> is there any project that I could look at?
<Papierkorb> zatherz, maybe Cinch, a irc bot lib in ruby
<RX14> don't use cinch as a base please
<RX14> i think it's pretty terrible API
<RX14> but for a list of features it's nice
<RX14> because it's bloated lol
<FromGitter> <drosehn> Hmm. What's the way to have `crystal` reformat a source file?
<FromGitter> <zatherz> `crystal tool format file`
<FromGitter> <drosehn> Ah, under `tool`. of course.
<FromGitter> <zatherz> I like the sublime 3 crystal plugin because it does that automatically on save
<FromGitter> <ltran> omg so cool =D
<FromGitter> <ltran> was wondering if there was something similar to Go’s fmt :D
<FromGitter> <zatherz> but yeah, I don't know how to keep it type safe but at the same time have a nice API for plugins that depend on other plugins' functionality
<jhass> I guess you could have some macro voodo that spits out a named tuple in the form of {plugin_name: PluginType, ...}
<Papierkorb> zatherz, hard to tell without more input. However, the gist is to have a module which defines the interface for the host program to the plugin. Like `received_message(sender, message)`. If you need dependencies, I'd have the providing plugin offer an interface (module, abstract class, ...) for other plugins. Then you have a PluginManager class, which can be asked to give all plugins implementing that interface. The plugin then gets a list
<Papierkorb> (or just the first match), and has a type safe way of communicating with the other plugin
<Papierkorb> zatherz, as shameless self promotion, you can also use the `cute` shard for program-local notifications, like receiving a message
<FromGitter> <zatherz> the dependency part is the only thing that gives me problems
<FromGitter> <zatherz> commands in my bot are implemented by a plugin
<Papierkorb> zatherz, more specific to chat bots, it's great to have a Message class which has a #reply method. a plugin can then simply do `message.reply "Okay!"`
<FromGitter> <zatherz> all plugins that want to use commands have to `include CorePlugin::CommandPlugin`, the thing is I want to separate some commands (like the plugin list or an `eval`) into a CoreCommandsPlugin
<FromGitter> <zatherz> `eval` specifically needs to use the parsing functionality of the core plugin
<FromGitter> <zatherz> maybe I should separate that part of the plugin
<FromGitter> <zatherz> into a CommandExecutor class or something like that
<FromGitter> <zatherz> then both CorePlugin and CoreCommandsPlugin would have an instance of that
<FromGitter> <zatherz> removing the need to refer to the loaded core plugin
<FromGitter> <jwoertink> I'm trying to create a simple matrix, but I keep getting Index out of bounds
<FromGitter> <jwoertink> ```code paste, see link``` []
<FromGitter> <zatherz> you have to use the shovel operator (`<<`) to add an object to an array
<FromGitter> <zatherz> you can't use `[]=`
<FromGitter> <zatherz> ```code paste, see link``` []
<FromGitter> <jwoertink> Still same error
<FromGitter> <zatherz> sorry, updated
<FromGitter> <jwoertink> `no overload matches 'Array(Int32)#<<' with type Array(Int32)`
<FromGitter> <zatherz> link?
bjz has joined #crystal-lang
<FromGitter> <zatherz> you didn't copy the updated code properly
<jhass> but there's a nicer way
<FromGitter> <jwoertink> hmm... I wanted to specify the index because this is more of simplified version of what I really want to do
<FromGitter> <zatherz> `[]=` on arrays makes no sense - what would happen in this case?
<FromGitter> <zatherz> ```x = [1] ⏎ x[2] = 3``` []
<FromGitter> <zatherz> also, you might want to use a matrix class
<FromGitter> <zatherz> like
<FromGitter> <jwoertink> in that case it would create an array like [1, nil, 3]
<FromGitter> <jwoertink> which is actually what I want
<FromGitter> <zatherz> but it's Array(Int32)
<FromGitter> <jwoertink> well, this sample is
<FromGitter> <zatherz> not Array(Int32?)
<FromGitter> <jwoertink> like I said, this is a lot more simplified example of what I'm really wanting to do
<FromGitter> <zatherz> well then, either use a premade matrix class like the above
<FromGitter> <zatherz> or make your own where
<jhass> crystal arrays don't autogrow since that's a common source of memory bloat bugs
<jhass> so you have to be explicit about any intermediate elements too
<FromGitter> <zatherz> `m[1, 1] = 2` will first fill in all the positions up to that point to nil
<FromGitter> <zatherz> and then will set the 1,1 element to 2
<FromGitter> <jwoertink> Ok, cool. I'll check out this matrix shard
<FromGitter> <zatherz> @jwoertink
<FromGitter> <zatherz> is this along the lines of what you want?
<FromGitter> <jwoertink> haha. That's a lot more code than I expected, but yeah pretty much
<FromGitter> <zatherz> it's not actually much code at all
<FromGitter> <jwoertink> This is what I'm porting over
<FromGitter> <jwoertink> which will have ints and nils in a giant matrix
<FromGitter> <zatherz> oh why did you not link that before >.<
<FromGitter> <jwoertink> lol
<FromGitter> <zatherz> ```code paste, see link``` []
<FromGitter> <zatherz> result ⏎ ⏎ ```[ ⏎ [0, 1, 2], ⏎ [1, 2, 3], ⏎ [2, 3, 4] ⏎ ]``` []
<FromGitter> <jwoertink> ah!
<FromGitter> <jwoertink> sweet. Thanks!
<FromGitter> <jwoertink> That will get me a lot closer
<FromGitter> <zatherz>
<FromGitter> <jwoertink> Awesome!
<FromGitter> <zatherz> I thought you wanted a general purpose mutable matrix that automatically grows lol
ga2mer has joined #crystal-lang
ga2mer has quit [Client Quit]
<FromGitter> <drosehn> Okay, I need a sanity check before I post an issue: if `low_value` and `high_value` start out as `nil`, then the loop construct of `until low_value && high_value` should have the exact same behavior as `while low_value.nil? || high_value.nil?`. True?
<FromGitter> <zatherz>
<FromGitter> <zatherz> `until low_value && high_value` is `while low_value.nil? || high_value.nil?`, yes
<FromGitter> <zatherz> what's the issue?
<FromGitter> <zatherz> @drosehn ^
<FromGitter> <drosehn> I'm posting the issue. Just re-reading it one more time to make sure I don't have any stupid typos or missing words.
Virviil has joined #crystal-lang
<FromGitter> <drosehn> But thanks for the check. Assuming I'm correct that what I found is a bug, then it seems odd that no one else has noticed it.
<FromGitter> <zatherz> why ` printf "#DBG B: low_value=%s, high_value=%s\n", low_value.inspect, high_value.inspect` instead of `puts "#DBG B: low_value=#{low_value}, high_value=#{high_value}"`?
<FromGitter> <drosehn> Does it really matter?
<FromGitter> <zatherz> well, the second is multitudes more readable
<FromGitter> <zatherz> but it doesn't matter in terms of the issue
bjz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
<FromGitter> <drosehn> This is cut down from a larger program. The larger program had one of those `printf`s. I changed it, and then duplicated the line to show the difference between the start and the end of the loop.
<FromGitter> <zatherz> @drosehn check this out
<FromGitter> <zatherz> same behavior as the until
<FromGitter> <drosehn> Er, the larger program had one `printf` in the loop, although the `printf` was printing something else for unrelated reasons. It didn't have *this* `printf`!
<FromGitter> <drosehn> huh. I didn't think to try that!
<FromGitter> <zatherz> the less expanded form `while !(low_value && high_value)`
<FromGitter> <zatherz> can also be used to reproduce this
Virviil has quit [Remote host closed the connection]
<FromGitter> <zatherz> so, basically, `while !(low_value && high_value)` produces a different result than `while !low_value || !high_value`
<FromGitter> <zatherz> @drosehn ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <zatherz> this is the same issue
<FromGitter> <zatherz> but minimized
<FromGitter> <drosehn> Indeed. Much easier to read.
<FromGitter> <zatherz> and it gave me an idea to check something
<FromGitter> <zatherz> @drosehn I think I found what causes the issue
<FromGitter> <zatherz> check this out
<FromGitter> <zatherz>
<FromGitter> <zatherz> the `a` inside that scope must be creating a new local variable
<FromGitter> <drosehn> But why is the new-local variable only created if the `a&&b` is done?
<FromGitter> <zatherz> I have no idea about that
<FromGitter> <zatherz> also, it must be caused by the `if`
<FromGitter> <zatherz> ```code paste, see link``` ⏎ ⏎ exits properly []
<FromGitter> <zatherz> actually, nevermind
<FromGitter> <zatherz> ```code paste, see link``` []
<FromGitter> <zatherz> you can reproduce this issue here without an infinite loop - the `a` at the end of the first loop is 2, but at the beginning of the first loop is nil
<FromGitter> <drosehn> Yeah, I just tried your code in a playground, and realized it was an infinite loop. :smile:
<FromGitter> <zatherz> even more visible here
bjz has joined #crystal-lang
DTZUZU has quit [Ping timeout: 260 seconds]
<FromGitter> <zatherz> @drosehn ⏎ ⏎ > DIT 2: ⏎ >Expanding the while condition of the first test from !(a && b) to !((a != nil) && b) produces expected behavior: ⏎ >But, expanding the condition from !(a && b) to !(!a.nil? && b) retains the unexpected effect: []
<FromGitter> <zatherz> replacing `(a != nil)` with `!a.nil?` has a different effect
bjz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
olek_poz has quit [Ping timeout: 260 seconds]
DTZUZU has joined #crystal-lang
<FromGitter> <drosehn> Thanks for all the extra examples. I expect they will be helpful.