ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.30.1 | 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
<FromGitter> <sam0x17> dont kno yet
<FromGitter> <sam0x17> in classic me fashion, I want to name it before I try to make it
<FromGitter> <tenebrousedge> it sounds easier to do that at runtime
<FromGitter> <sam0x17> my use case is I'm in all these kemal endpoints and wish I could just `return` sometimes so I `next` a string or json or whatever, but if I'm in an `.each` block etc I can't do that and it gets so awk
<FromGitter> <tenebrousedge> using `each` is probably one problem there
<FromGitter> <sam0x17> e.g.: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d6867b4a563676ace90ddd0]
<FromGitter> <Blacksmoke16> looks like you could use my validation shard πŸ˜‰
<FromGitter> <sam0x17> I totally should -- just want to get parity between old rails app and new crystal version before I start trying to revamp things
<FromGitter> <Blacksmoke16> doesnt halt do it?
<FromGitter> <sam0x17> that's a good point, I should try that again
<FromGitter> <sam0x17> I think it does if I specify the mime type etc
<FromGitter> <Blacksmoke16> or raises an exception that gets caught
<FromGitter> <Blacksmoke16> to return the json error message
<FromGitter> <sam0x17> hah you are right I actually have stuff in place for formatting the exception messages too
<FromGitter> <sam0x17> !!!
<FromGitter> <didactic-drunk> Is there way to get all superclasses in a macro that have a particular module included or constant defined? I'd prefer the module if there's a choice.
<FromGitter> <sam0x17> in this case that is what I should do lol thanks @Blacksmoke16
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d68685b8deffa6acfa28397]
<FromGitter> <sam0x17> I've been doing it in middleware already just didn't think to do it in an endpoint
<FromGitter> <Blacksmoke16> something like that
<FromGitter> <sam0x17> yeah
<FromGitter> <sam0x17> I have exactly that
<FromGitter> <sam0x17> Im stupid lol
<FromGitter> <watzon> Hey look who it is. Long time no see @didactic-drunk
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <sam0x17> but on that note, would still be cool to have like a super `next` lol
<FromGitter> <sam0x17> or even better `next(2)` (breaks two levels up) lolol
<FromGitter> <Blacksmoke16> `exit` :trollface:
<FromGitter> <sam0x17> hah
<FromGitter> <sam0x17> in a lambda it wouldn't even be so bad
<FromGitter> <sam0x17> because it would spawn a new one
<FromGitter> <Blacksmoke16> @didactic-drunk i dont think you can get modules included in a type atm
<FromGitter> <Blacksmoke16> depending on what you're trying to do, might be able to use an annotation
<FromGitter> <Blacksmoke16> or the constant
<FromGitter> <Blacksmoke16> holy shit https://crystal-lang.org/api/master/Crystal/Macros/TypeNode.html#has_attribute?(name:StringLiteral%7CSymbolLiteral):BoolLiteral-instance-method
<FromGitter> <Blacksmoke16> TIL thats a thing
<FromGitter> <Blacksmoke16> needs renamed and docs updated tho
<FromGitter> <Blacksmoke16> ehh actually it doesnt work how i thought. needs fixedc
<FromGitter> <didactic-drunk> @watzon Wow you respond quickly here. I was going to check back in 3 months based on our last discussion.
<FromGitter> <didactic-drunk> Oh great, he's gone again. Maybe he needs more cat pictures (https://github.com/watzon/nacl/issues/1#issuecomment-504764776).
<FromGitter> <tenebrousedge> probably needs more cat pictures. Maybe of actual cats this time
<FromGitter> <didactic-drunk> There's at least 1 non edible cat in link.
<FromGitter> <tenebrousedge> non...edible...cat? o__O
<FromGitter> <tenebrousedge> but they give you those warm fuzzy feelings inside
<FromGitter> <didactic-drunk> You mean blood and hair balls? Yeszzz..
<FromGitter> <watzon> Where are the pics?
<FromGitter> <watzon> You summoned me, I expect pics
<FromGitter> <didactic-drunk> Tried sending D pics. Apparently those also get your account suspended. Not eager to have it happen a 4th time (See project history at bottom) (https://github.com/didactic-drunk/sodium.cr).
<FromGitter> <Blacksmoke16> anyone familiar with XML?
<FromGitter> <Blacksmoke16> i think i found a bug
<FromGitter> <tenebrousedge> a bug in...XML?
<FromGitter> <Blacksmoke16> well in the crystal type enum :p
<FromGitter> <Blacksmoke16> `DTD_NODE` should be `SignificantWhitespace`
<FromGitter> <Blacksmoke16> and `ELEMENT_DECL` should be called `END_ELEMENT`
<FromGitter> <Blacksmoke16> right?
<FromGitter> <tenebrousedge> this is just a naming issue, yes? does it affect correctness or performance in some way?
<FromGitter> <Blacksmoke16> affected me wondering wtf a `DTD_NODE` is when i dont see any other nodes
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/7gwt
<FromGitter> <tenebrousedge> maybe we're copying this https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node
<FromGitter> <Blacksmoke16> sure looks like it
<FromGitter> <Blacksmoke16> let me try it in ruby?
<FromGitter> <Blacksmoke16> actually i dont have ruby so nvm
<FromGitter> <tenebrousedge> oh, you should look into Ruby, it's good for prototyping Crystal programs
<FromGitter> <Blacksmoke16> meh, anyway ill make an issue. sure seems like its wrong
<FromGitter> <watzon> @Blacksmoke16 is featured in this weeks edition of Crystal Lib Hunt
<FromGitter> <Blacksmoke16> did i just happen to have the only post this week? :p
<FromGitter> <Blacksmoke16> neat
<FromGitter> <watzon> I think so πŸ˜‚
<FromGitter> <watzon> I was going to write one, but I've been too busy
<FromGitter> <Blacksmoke16> hehe
<FromGitter> <watzon> Can anyone think of a reason why running `shards install` would ask for a github username and password? @rmarronnier is trying to install https://github.com/cadmiumcr/tokenizer, but it's asking for a username and password. When I try it locally it works just fine.
<FromGitter> <watzon> Maybe someone else could test it and see if it installs correctly?
<FromGitter> <Blacksmoke16> make sure the github path is correct
<FromGitter> <Blacksmoke16> and its not a private repo
<FromGitter> <watzon> Should be correct, and definitely isn't private
<FromGitter> <Blacksmoke16> whats his shard.yml look like/
<FromGitter> <watzon> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d688c9c336d8510a20d95ac]
<FromGitter> <Blacksmoke16> worked fine for me
<FromGitter> <watzon> Ok so it must be something to do with your git config @rmarronnier
<FromGitter> <rmarronnier> Damn, I'll look into this. Good news for everyone else though
<FromGitter> <watzon> Yep lol. I'm assuming you're using ssh?
<FromGitter> <dmitryrck> `shards install` works for me too with that `shard.yml` :P
<FromGitter> <watzon> I guess it's working for him now
<FromGitter> <watzon> Why it wasn't before we may never know
chemist69 has quit [Ping timeout: 276 seconds]
chemist69 has joined #crystal-lang
<FromGitter> <dmitryrck> is there any way to add an spy in `puts` using *only* stdlib? ⏎ I want to test if `puts` is called and with the correct argument πŸ€”
<FromGitter> <dmitryrck> (automated test, BTW)
<FromGitter> <watzon> @dmitryrck what do you mean "add a spy"?
<FromGitter> <dmitryrck> I want to be able to write a test like this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d68a8e5bee75051a41eca20]
<FromGitter> <dmitryrck> of course, this `expect().to receive` is a DSL that I don't have, anything similar helps :)
<FromGitter> <watzon> Oh yeah, you can't do that. The best you could hope for is to monkeypatch the `puts` method. There is another spec library called Spectator (https://github.com/icy-arctic-fox/spectator) that is going to be implementing mocks soon.
<FromGitter> <watzon> But I doubt the built in spec library will ever be capable
<FromGitter> <watzon> Or at least not soon
<FromGitter> <dmitryrck> yeah, that is what I just tried ⏎ I also tried dependency injection ⏎ I will try dependency injection, it is probably the best to do here πŸ€” ⏎ in ruby `puts` is from `Kernel`, I have not done anything similar in Ruby, but I supposed it is possible `allow(Kernel).to receive(:puts)` (emphasis to *suppose*) ⏎ in Crystal it is from a constant [https://gitter.im/cry
<FromGitter> ... stal-lang/crystal?at=5d68aa9e85a9157cb44a6eba]
<FromGitter> <dmitryrck> actually, I did not try monkey patch properly, I felt like it was not a good idea, even thou I would write only in `spec/spec_helper.cr` :P
<FromGitter> <watzon> Well `puts` is in the top level namespace. Technically you could wrap it as well and just create your own `puts` method that wraps puts and handle your own logic there.
<FromGitter> <dmitryrck> πŸ€”
<FromGitter> <dmitryrck> thanks for the idea, I will see what I can do, maybe I even write a blog post ⏎ see ya o/
absolutejam1 has joined #crystal-lang
<FromGitter> <absolutejam_gitlab> I've done in a class because I wanted to be able to silence `puts` when testing
<FromGitter> <absolutejam_gitlab> and just call `::puts` if I want the original version
<FromGitter> <absolutejam_gitlab> Not sure I'm not using a logger though, maybe I need to revisit
<FromGitter> <absolutejam_gitlab> TIL `delegate get_usable_flag, to: get_usable_flag_by_name`
<FromGitter> <dmitryrck> yeah, I've done that: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ and everything is green ... [https://gitter.im/crystal-lang/crystal?at=5d68bb92fda04e4c9d3f9ace]
<FromGitter> <dmitryrck> many thanks :D
sagax has joined #crystal-lang
devil_tux has joined #crystal-lang
absolutejam1 has quit [Ping timeout: 272 seconds]
Raimondi has quit [Ping timeout: 258 seconds]
Raimondi has joined #crystal-lang
Raimondi has quit [Ping timeout: 248 seconds]
<FromGitter> <absolutejam_gitlab> http://podplayer.net/?id=79503179
<FromGitter> <absolutejam_gitlab> Coder radio talking about Crystal
Raimondi has joined #crystal-lang
<FromGitter> <watzon> @dmitryrck yeah spectator will be adding mocking in the near future. I am needing it for a project as well.
ua has quit [Ping timeout: 272 seconds]
DTZUZO has quit [Ping timeout: 245 seconds]
ua has joined #crystal-lang
absolutejam1 has joined #crystal-lang
sagax has quit [Read error: Connection reset by peer]
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 244 seconds]
DTZUZO has joined #crystal-lang
sagax has joined #crystal-lang
devil_tux has quit [Ping timeout: 272 seconds]
alex`` has joined #crystal-lang
devil_tux has joined #crystal-lang
DTZUZO has quit [Read error: Connection reset by peer]
kazooie___ has joined #crystal-lang
DTZUZO has joined #crystal-lang
devil_tux has quit [Ping timeout: 244 seconds]
absolutejam1 has quit [Ping timeout: 244 seconds]
hightower2 has quit [*.net *.split]
teardown has quit [*.net *.split]
commavir has quit [*.net *.split]
wmoxam has quit [*.net *.split]
justinmcp_ has quit [*.net *.split]
Human_G33k has quit [*.net *.split]
Stephie has quit [*.net *.split]
blassin has quit [*.net *.split]
olbat has quit [*.net *.split]
wmoxam has joined #crystal-lang
Vexatos has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
justinmcp has joined #crystal-lang
absolutejam1 has joined #crystal-lang
Vexatos has joined #crystal-lang
teardown has joined #crystal-lang
commavir has joined #crystal-lang
devil_tux has joined #crystal-lang
Stephie has joined #crystal-lang
absolutejam1 has quit [Quit: WeeChat 2.5]
Human_G33k has quit [Read error: Connection reset by peer]
absolutejam has joined #crystal-lang
<FromGitter> <dmitryrck> πŸ™
devil_tux has quit [Ping timeout: 246 seconds]
ht_ has joined #crystal-lang
devil_tux has joined #crystal-lang
<FromGitter> <Blacksmoke16> dunno if its important or not, but ofc `puts` always outputs to STDOUT
<FromGitter> <Blacksmoke16> could also do like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d690f5138499c13a66df80e]
<FromGitter> <Blacksmoke16> then for testing you could do like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d690fb37b263a4c9c7ed5a9]
<FromGitter> <absolutejam_gitlab> that's nice
<FromGitter> <Blacksmoke16> or even if you used a logger
<FromGitter> <Blacksmoke16> then at least you have control over where the output goes
<FromGitter> <Blacksmoke16> ```LOGGER = Logger.new STDOUT ⏎ ... ⏎ LOGGER.puts content``` [https://gitter.im/crystal-lang/crystal?at=5d691117b4d82940749ecb31]
HumanG33k has joined #crystal-lang
<FromGitter> <Daniel-Worrall> Is there a native way to pull urls from a string?
<FromGitter> <Daniel-Worrall> saving me from regex'ing them out
<FromGitter> <tenebrousedge> I'm pretty sure no
<FromGitter> <tenebrousedge> definitely not in `String`
<FromGitter> <Daniel-Worrall> Well, it doesn't have to be a String method, but it could *take* a string
<FromGitter> <tenebrousedge> there's a URI class https://crystal-lang.org/api/0.20.1/URI.html
<FromGitter> <Daniel-Worrall> Yeah, that's what I was going to use to parse it once it was extracted
<FromGitter> <Daniel-Worrall> Oh well, I'll just parse it
<FromGitter> <tenebrousedge> yeah, I think you'll need to, sorry
<FromGitter> <Blacksmoke16> whats the string look like
<FromGitter> <Daniel-Worrall> it's for Twitch Webhook stuff
<FromGitter> <Daniel-Worrall> I want the data from the second url to identify what the payload is for
<FromGitter> <Blacksmoke16> and its just a string? not from headers or something?
<FromGitter> <Daniel-Worrall> This is a string that came from a header
<FromGitter> <Daniel-Worrall> from a link header
<FromGitter> <Daniel-Worrall> `env.request.headers["link"]`
<FromGitter> <Daniel-Worrall> It's also possible I'm just using Kemal wrong
<FromGitter> <Blacksmoke16> i dont have any ideas, regex and parse with URI seems to be best bet
<FromGitter> <Daniel-Worrall> Does Kemal have a method I can use to parse the query params?
<FromGitter> <Daniel-Worrall> Saving me from doing it myself
<FromGitter> <Daniel-Worrall> Perhaps ParamParser
<FromGitter> <Blacksmoke16> once you get it in URI form you can new up an `HTTP::Params`
<FromGitter> <Daniel-Worrall> Ah, great
<FromGitter> <Blacksmoke16> next crystal version will make it easier as well
<FromGitter> <Blacksmoke16> well after https://github.com/crystal-lang/crystal/pull/8090 is merged
<FromGitter> <Daniel-Worrall> sweet
kazooie___ has quit [Ping timeout: 268 seconds]
devil_tux has quit [Ping timeout: 268 seconds]
gangstacat has joined #crystal-lang
absolutejam has quit [Ping timeout: 245 seconds]
<FromGitter> <kinxer> @Blacksmoke16 `Assert` looks useful. Small gripe with the API docs, though: the Assert::Assertions page (https://blacksmoke16.github.io/assert/Assert/Assertions.html) doesn't actually have a full list.
absolutejam has joined #crystal-lang
<FromGitter> <Daniel-Worrall> @Blacksmoke16 Do you know if there's a way to read the request body so that I can parse the body as json later as well? `env.request.body` returns a `HTTP::FixedLength` so if I `gets_to_end`, I can't `rewind` and a call to `env.params.json` attempts to parse the now empty io
<FromGitter> <Daniel-Worrall> I came across an old issue https://github.com/kemalcr/kemal/issues/478 but that just delayed the param parser to the method calls.
<FromGitter> <Daniel-Worrall> So there doesn't seem to be a way to do both
<FromGitter> <Daniel-Worrall> carc.in doesn't seem to be working
<FromGitter> <Daniel-Worrall> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d693aea0d4b1f5d8886a1ff]
<FromGitter> <Daniel-Worrall> w/e
<FromGitter> <Daniel-Worrall> this is what I have that works but it's so hacky
<FromGitter> <Daniel-Worrall> and doesn't work with the HTTP::FixedLength anyway
absolutejam has quit [Ping timeout: 245 seconds]
<FromGitter> <Blacksmoke16> @kinxer its more so linking to the namespace
<FromGitter> <Blacksmoke16> i.e. can see all them in the list on the left
<FromGitter> <Blacksmoke16> whats a `HTTP::FixedLength`?
<FromGitter> <Blacksmoke16> pretty sure you can just do like `json = env.request.body.not_nil!.gets_to_end`
<FromGitter> <Blacksmoke16> ofc prob not actually use `.not_nil!`, i.e. make sure there is a body first and return some error if not
<FromGitter> <Blacksmoke16> @Daniel-Worrall
<FromGitter> <Daniel-Worrall> HTTP::FixedLength is a nodoc of IO::Sized with some more methods
<FromGitter> <kinxer> Oh, okay. I expected to seem them listed in the main page space.
<FromGitter> <Daniel-Worrall> I can do that, I was hoping Kemal could handle it better
<FromGitter> <Blacksmoke16> i could but would kinda be redundant and would have to remember to update it if you add/edit any assertions
<FromGitter> <kinxer> Solid article, btw. I don't really do any web development or server-side work, but I'll keep `Assert` in mind.
<FromGitter> <kinxer> Yeah, that makes sense. I don't know if it was the wording or me just misunderstanding.
<FromGitter> <Blacksmoke16> thanks :)
DTZUZU has joined #crystal-lang
<FromGitter> <Blacksmoke16> planning on doing another blog post to highlight some implementation details that are quite slick
<FromGitter> <Blacksmoke16> @Daniel-Worrall so whats you're goal here? get the parse JSON AND the raw string?
<FromGitter> <Daniel-Worrall> yeah
<FromGitter> <Blacksmoke16> id just do it yourself then
<FromGitter> <Daniel-Worrall> I'm doing it that way now
<FromGitter> <Blacksmoke16> ```raw_json = env.request.body.not_nil!.gets_to_end ⏎ parsed_json = JSON.parse(raw_json)``` [https://gitter.im/crystal-lang/crystal?at=5d69414d0d4b1f5d8886cd63]
<FromGitter> <Daniel-Worrall> The library should be able to handle both :^)
<FromGitter> <Blacksmoke16> or ideally abstract the parsing and just give you an object that represents it
devil_tux has joined #crystal-lang
<FromGitter> <meltheadorable> that’s a weird enough use case i see no reason it should be built in
<FromGitter> <Blacksmoke16> could also prob just call `.to_json` on the parsed data
<FromGitter> <Daniel-Worrall> I need it to check against a sha signature on the header to verify the payload
<FromGitter> <Daniel-Worrall> but the payload is json, which I will need to parse
<FromGitter> <Daniel-Worrall> Can't call `#to_json` because it'll give a different result to the raw string
<FromGitter> <Daniel-Worrall> and so the sha will be different
<FromGitter> <Blacksmoke16> could make it some before action
<FromGitter> <Blacksmoke16> like middleware or something
<FromGitter> <Daniel-Worrall> Will that give me access to the raw string without messing with later parsing though
<FromGitter> <Daniel-Worrall> I don't know if it provides the same `env`
<FromGitter> <Daniel-Worrall> I could try it
<FromGitter> <Blacksmoke16> naw, pretty sure it would be the same
<FromGitter> <Daniel-Worrall> If it's the same, it'd be the same problem
<FromGitter> <Daniel-Worrall> I'm just reworking the code
<FromGitter> <Daniel-Worrall> and parsing myself
<FromGitter> <Blacksmoke16> πŸ‘
Yxhuvud has joined #crystal-lang
Human_G33k has joined #crystal-lang
<FromGitter> <Daniel-Worrall> Okay, how do I actually sha256 something
<FromGitter> <Daniel-Worrall> I'm getting lost
HumanG33k has quit [Ping timeout: 245 seconds]
<FromGitter> <Blacksmoke16> `hash = OpenSSL::Digest.new("SHA256").update(str).to_s`
<FromGitter> <Blacksmoke16> afaik
<FromGitter> <Daniel-Worrall> ty, I got the same thing from https://www.toptal.com/blockchain/crystal-programming-language-tutorial
<FromGitter> <Daniel-Worrall> except calling `#hexdigest` instead of `#to_s`
<FromGitter> <Blacksmoke16> prob do the same thing
<FromGitter> <kingsleyh> hey - what is the best way of writing stout to file in realtime while a long running process is running - e.g.
<FromGitter> <kingsleyh> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d694f987b263a4c9c80a4b2]
<FromGitter> <Blacksmoke16> `output: STDOUT)`?
<FromGitter> <kingsleyh> I want to write it to a file
<FromGitter> <Blacksmoke16> oh
<FromGitter> <Blacksmoke16> why not just write to STDOUT and pipe the output to the file?
<FromGitter> <Blacksmoke16> like `./myApp > file.log`
<FromGitter> <kingsleyh> I tried that and it doesn't work very well - the logs are written only half way through the process and then missing a big chunk from the end
<FromGitter> <kingsleyh> I want realtime logs
<FromGitter> <Blacksmoke16> could use the multiwriter then maybe
<FromGitter> <Blacksmoke16> one being a file, other being stdout?
<FromGitter> <kingsleyh> can't I just write the IO::Memory to file everytime it gets something?
<FromGitter> <kingsleyh> some kind of while sdout.gets then append to file
<FromGitter> <asterite> `file = File.open("..."); Process.run(..., output: file)`
<FromGitter> <Blacksmoke16> yea that
<FromGitter> <asterite> if you need to write to a file and STDOUT then use MultiWriter
<FromGitter> <Blacksmoke16> im assuming you dont need to worry about closing the file? that would happen when your program exists?
<FromGitter> <Blacksmoke16> exits*
<FromGitter> <kingsleyh> great thanks
<FromGitter> <kingsleyh> hmm doesn't work very well either
<FromGitter> <kingsleyh> the Process.run is inside a spawn - maybe this is causing a problem
<FromGitter> <kingsleyh> the log file is created immediately but has no content for a long time
<FromGitter> <Blacksmoke16> try doing like
<FromGitter> <Blacksmoke16> ```file = File.open("...") ⏎ file.sync = true ⏎ Process.run(..., output: file)``` [https://gitter.im/crystal-lang/crystal?at=5d6955117b263a4c9c80d0e4]
<FromGitter> <Blacksmoke16> was prob only flushing when the buffer was full
<FromGitter> <kingsleyh> I should use File.open("name.txt", "a") for append right?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Daniel-Worrall> Okay, I'm dumb, I needed a HMAC
<FromGitter> <Blacksmoke16> rip
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/OpenSSL/HMAC.html prob that htne
<FromGitter> <kingsleyh> gah - still not writing anything to the file
<FromGitter> <Daniel-Worrall> Yeah, I've sorted it now
<FromGitter> <Blacksmoke16> cool
<FromGitter> <Blacksmoke16> yea i dunno without having something to reproduce it with
<FromGitter> <kingsleyh> when I use STDOUT the output is written to the screen immediately
<FromGitter> <Blacksmoke16> what was the issue with just doing that then `> out.log`?
<FromGitter> <kingsleyh> but when using a file or another IO thing - the output is not written until the end of the long running proceess
<FromGitter> <kingsleyh> doing > out.log has the same issue as above
<FromGitter> <Blacksmoke16> what if you do `> out.log` but with `output: Process::Redirect::Inherit`
<FromGitter> <asterite> that's with `sync = true`? Let me try it
<FromGitter> <asterite> it works for me
<FromGitter> <asterite> maybe the process you are calling needs to flush the output?
<FromGitter> <kingsleyh> hmm
<FromGitter> <kingsleyh> what do you mean do `> out.log` when using the output:
<FromGitter> <Blacksmoke16> `Process.run(..., output: Process::Redirect::Inherit)`
<FromGitter> <Blacksmoke16> then like `./myApp > out.log`
<FromGitter> <kingsleyh> the Process.run is executing the myApp tho
<FromGitter> <Blacksmoke16> then what triggers the exec function?
<FromGitter> <Blacksmoke16> i.e. the process
<FromGitter> <kingsleyh> There is a co-ordinator app called e2e.cr
<FromGitter> <kingsleyh> and it calls spawn with the Process in it
<FromGitter> <kingsleyh> as it starts 3 of the processess
<FromGitter> <kingsleyh> but right now I'm trying to get 1 process to run and log in realtime
<FromGitter> <kingsleyh> when I did "./myprocess > out.log" there was no logging until nearly the end of the process run - which is 15 mins
<FromGitter> <kingsleyh> that was using a system("./myprocess > out.log")
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <kingsleyh> when I change to using `Process.new(command, shell: true, output: file)`
<FromGitter> <kingsleyh> same behaviour
<FromGitter> <Blacksmoke16> even after doing `file.sync = true`?
<FromGitter> <kingsleyh> but when I use: `Process.new(command, shell: true, output: STDOUT)` - the output is immediately written to the screen
<FromGitter> <kingsleyh> yeah
<FromGitter> <kingsleyh> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d695d1f29dba2421cd4e430]
<FromGitter> <kingsleyh> something to do with shell: true maybe?
<FromGitter> <asterite> what's the command?
<FromGitter> <kingsleyh> its `/Users/kings/dev/projects/SushiChain/bin/sushid -p 4001 -w /Users/kings/dev/projects/SushiChain/e2e/wallets/testnet-0.json --testnet -d /Users/kings/dev/projects/SushiChain/e2e/db/e68a24c3b56b5efde76fe6073fe75d86.db -u http://127.0.0.1:4001`
<FromGitter> <asterite> In sushid try doing `STDOUT.sync = true`
<FromGitter> <asterite> we changed something in one of the latest versions to only flush immediately when the output is a tty
<FromGitter> <asterite> if it's not then it's not flushed immediately
<FromGitter> <asterite> maybe that was a mistake, I don't know
<FromGitter> <asterite> though it works like that in Ruby too
<FromGitter> <asterite> alteratively, each time `sushid` outputs you can call `flush`
<FromGitter> <asterite> we should probably revert that change and make STDOUT be `sync = true` by default...
<FromGitter> <kingsleyh> hmm ok thanks
<FromGitter> <kingsleyh> @asterite AWESOME - that works thanks - I would never have figured that out lol
<FromGitter> <asterite> Cool!
<FromGitter> <asterite> I just reopened an issue about it: https://github.com/crystal-lang/crystal/issues/7431#issuecomment-526686589
<FromGitter> <kingsleyh> thanks
absolutejam has joined #crystal-lang
absolutejam has quit [Ping timeout: 258 seconds]
devil_tux has quit [Ping timeout: 245 seconds]
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
dannyAAM has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
ua has quit [Ping timeout: 245 seconds]
kazooie___ has joined #crystal-lang
<FromGitter> <stronny> hi guys, there is this issue: https://github.com/crystal-lang/crystal/issues/6677, and it mentions at the end that static arrays take a long time to compile inside LLVM iiuc
<FromGitter> <stronny> it also causes the binary to grow in size. is there anything I can do to avoid this effect besides not using them?
ua has joined #crystal-lang
gangstacat has quit [Quit: Ĝis!]
gangstacat has joined #crystal-lang
kazooie___ has quit [Ping timeout: 246 seconds]
<FromGitter> <asterite> I don't think so, it's an LLVM issue
devil_tux has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
devil_tux has quit [Ping timeout: 258 seconds]
<FromGitter> <stronny> got it, thanks
ht_ has quit [Remote host closed the connection]
absolutejam has joined #crystal-lang
ht_ has joined #crystal-lang
ht_ has quit [Quit: ht_]
<FromGitter> <watzon> Has @Blacksmoke16 done any blog posts/tutorials on using annotations? I think I'm going to change Tourmaline to have an annotation based API.
<FromGitter> <watzon> But I haven't even touched that part of Crystal yet
<FromGitter> <Blacksmoke16> the validation stuff is a bit out of date, as i came up with a better way
<FromGitter> <watzon> I still don't get why annotations are blocks if they don't have anything inside of them
<FromGitter> <watzon> It would make more sense for them to be kind of like abstract methods
<FromGitter> <Blacksmoke16> prob in case of future features
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <watzon> Hmm
<FromGitter> <watzon> I mean it would be cool if you could handle the annotation logic inside of the annotation definition
<FromGitter> <Blacksmoke16> indeed
<FromGitter> <watzon> Gonna do something like this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69a9480d4b1f5d8889bd26]
<FromGitter> <watzon> Gonna do something like this
<FromGitter> <watzon> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69a9972efeca1df5238f4d]
<FromGitter> <watzon> Wish me luck
<FromGitter> <Blacksmoke16> and what would they do/
<FromGitter> <Blacksmoke16> like whats the end goal?
<FromGitter> <watzon> Well Tourmaline is a Telegram Bot framework. The `Command` annotation is going to register the method as a command. In the top example it will register the command `/help` to send a help message. `at_start: true` is going to make sure that the method is only called if the command is found at the beginning of a message. ⏎ ⏎ The second one is going to be a general event listener. There are a ton of potential
<FromGitter> ... events.
<FromGitter> <watzon> Right now I
<FromGitter> <watzon> But I want to make it a bit more friendly for actually extending `Tourmaline::Bot`. Right now it's a pain in the ass.
<FromGitter> <Blacksmoke16> should be doable yea
<FromGitter> <Blacksmoke16> does every command only have those 2 args?
<FromGitter> <watzon> For now. Right now the second arg doesn't even exist, but it's something I want to add.
absolutejam has quit [Ping timeout: 258 seconds]
<FromGitter> <Blacksmoke16> do what i would do is like
<FromGitter> <Blacksmoke16> have a parent class that all the command stuff inherits from
<FromGitter> <Blacksmoke16> then you can iterate over the children, iterate over methods, and "register" those that have the ann
<FromGitter> <Blacksmoke16> registration could be like `Hash(String, Proc(message : Message, Nil))`
<FromGitter> <Blacksmoke16> then like ⏎ ⏎ ```if cmd = get_command(ARGV);``` [https://gitter.im/crystal-lang/crystal?at=5d69abe68066a340732106ad]
<FromGitter> <watzon> So each command would be a class instead of a method?
<FromGitter> <watzon> And then the command class would be annotated?
<FromGitter> <Blacksmoke16> no, you just need some way to get an array of classes that *could* have commands
<FromGitter> <Blacksmoke16> sec
<FromGitter> <watzon> Ahh I think I understand
<FromGitter> <watzon> This is more or less what I was thinking a very basic bot example would look like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69ac7929dba2421cd70654]
<FromGitter> <watzon> So in this case it would be looping over the methods in `Tourmaline::Bot`
<FromGitter> <Blacksmoke16> any reason they should be instance methods?
<FromGitter> <watzon> Not any specific reason, other than semantics
<FromGitter> <watzon> Having to extend self or do `self.` for every method is more work and not very nice looking if I can help it.
<FromGitter> <watzon> But I'm open to suggestions, you're Yoda in this situation. I'm merely young Luke Skywalker.
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69adf58066a34073211251]
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69ae84b156cd5e75b19947]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69aea1b156cd5e75b199e2]
<FromGitter> <Blacksmoke16> something along those lines?
<FromGitter> <watzon> Is there any reason I couldn't loop over methods in subclasses of `Tourmaline::Bot`?
<FromGitter> <Blacksmoke16> thats essentially what this is doing
<FromGitter> <Blacksmoke16> just replace `BotCommand` with `Tourmaline::Bot`
<FromGitter> <watzon> Ok cool, just making sure I wasn't misunderstanding
<FromGitter> <watzon> This is awesome
<FromGitter> <watzon> Gonna make my API much cleaner
<FromGitter> <Blacksmoke16> if you wanted to go the instance method route its possible
<FromGitter> <Blacksmoke16> but pros and cons ofc
<FromGitter> <watzon> What are the cons?
<FromGitter> <watzon> Or is there any reason I couldn't do both?
<FromGitter> <Blacksmoke16> actually sec
<FromGitter> <watzon> Come to think of it I do need them to be instance methods
<FromGitter> <watzon> They need access to other instance methods/variables
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5d69b0ac375cc34fdee984bc]
<FromGitter> <Blacksmoke16> assuming they dont have any dependencies?
<FromGitter> <Blacksmoke16> otherwise DI would work well here, as you wouldnt have to manually give it anything
<FromGitter> <Blacksmoke16> could all be resolved from the container
<FromGitter> <watzon> So this would work for class and instance methods?
<FromGitter> <Blacksmoke16> this handles instance
<FromGitter> <Blacksmoke16> main challenge with that is you have to new up a class first
<FromGitter> <watzon> Right, which I'm ok with. I want users to have to subclass `Tourmaline::Bot`.
<FromGitter> <Blacksmoke16> but there arent any dependencies you have to give it right?
<FromGitter> <Blacksmoke16> like MyCommandClas.new x, y, z
<FromGitter> <watzon> Right now `Tourmaline::Client` requires an `api_key` argument, but that's it.
<FromGitter> <Blacksmoke16> hm ok
<FromGitter> <Blacksmoke16> have a few options
<FromGitter> <Blacksmoke16> idk how you want all this to work but the idea is you can iterate children of your parent class, iterate methods, and do something with the methods with that annotation
<FromGitter> <Blacksmoke16> possibly converting the methods into procs to call later
<FromGitter> <Blacksmoke16> is essentially how athena works
<FromGitter> <watzon> That's the ideal situation
<FromGitter> <Blacksmoke16> sounds like a plan :p
<FromGitter> <watzon> Right now that code would just work with subclasses right? What if I wanted to define a command on the base class?
<FromGitter> <Blacksmoke16> like a common command that all children should have?
<FromGitter> <Blacksmoke16> or like default commands
<FromGitter> <Blacksmoke16> for the app
<FromGitter> <watzon> Like a common command. Tbh this wouldn't be for commands, but for event listeners.
<FromGitter> <watzon> Because it's actually a default event listener that calls the commands.
<FromGitter> <watzon> Although...
<FromGitter> <watzon> I don't actually need to do that, nvm
<FromGitter> <Blacksmoke16> in that case you can either define those on a subclass
<FromGitter> <Blacksmoke16> or add another loop to loop over main class methods
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <watzon> Yeah cool. Well awesome. I'll try and implement this. Should be pretty cool if I can get it working.
<FromGitter> <Blacksmoke16> indeed, they allow for some cool things
<FromGitter> <Blacksmoke16> mainly compile time errors and caching since everything gets registered at compile time