ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.33.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
<FromGitter> <j8r> How others do to store procs of different types?
<FromGitter> <Blacksmoke16> athena handles it by each route action (method) getting its own `Route` instance that uses generics
<FromGitter> <j8r> I can avoid the Generric, it means potentially creating a new hash each type a Proc is added to increase the Union
<FromGitter> <Blacksmoke16> then the router just returns the correct `Route` instance based based on the request uri
<FromGitter> <j8r> The should be an union somewhere, no?
<FromGitter> <Blacksmoke16> union of what?
<FromGitter> <j8r> Each Route can return a different type
<FromGitter> <Blacksmoke16> right
<FromGitter> <Blacksmoke16> there isnt a union since each route has its own proc representing that action
<FromGitter> <Blacksmoke16> so the result of executing a given route would only ever be the type of the generic
<FromGitter> <j8r> The return type of the action proc can vary?
<FromGitter> <Blacksmoke16> nope
<FromGitter> <Blacksmoke16> its based on the return type of the method
<FromGitter> <Blacksmoke16> ```def some_action : String ⏎ "foo" ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e488bdbc8da1343d4535517]
<FromGitter> <Blacksmoke16> the route tied to that action would always be ofc a `String`
<FromGitter> <j8r> So it will be `Route(String)`, which stores a `Proc(..., String)`?
<FromGitter> <Blacksmoke16> granted there isnt anything preventing you from doing `: String | Int32` or whatever, but 😬
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> `Route(Cont, Proc(Proc(String)), String)`
<FromGitter> <Blacksmoke16> `Cont` is my controller class
<FromGitter> <Blacksmoke16> double proc is the action, and last `String` is return type
<FromGitter> <Blacksmoke16> double proc is mainly so each request gets its own controller instance (for DI to work better)
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/8520 once this is resolved i wont have to have a generic explicitly for the proc
<FromGitter> <Blacksmoke16> as internally it could just be `Proc(Proc(*Args, ReturnType))`
<FromGitter> <j8r> I see, thanks
<FromGitter> <j8r> My logic is a bit similar
<FromGitter> <Blacksmoke16> np, also be aware of https://github.com/crystal-lang/crystal/issues/7698
<FromGitter> <Blacksmoke16> that was a pita to figure out
<FromGitter> <j8r> A route node will take `Node(Action(T))`
<FromGitter> <Blacksmoke16> yea, essentially same setup
<FromGitter> <Blacksmoke16> sounds like a plan
<FromGitter> <Blacksmoke16> whats your plan for error handling?
<FromGitter> <j8r> There is a `Final` handler(s) that executes always at the end
<FromGitter> <j8r> An `Exception?` argument is passed
<FromGitter> <j8r> Is allows to log both the request and the error log with the exact same Time
<FromGitter> <j8r> Even if i would prefer to seprate both
<FromGitter> <Blacksmoke16> how does that work in practice? like can the user control how the exception is handled or?
<FromGitter> <j8r> The user can set its own handler yes
<FromGitter> <Blacksmoke16> gotcha
<FromGitter> <j8r> That's mainly for logging
<FromGitter> <Blacksmoke16> ah, i was thinking like 404, 400, etc
<FromGitter> <j8r> Ho yes
<FromGitter> <Blacksmoke16> as how you handle that would depend on if you have an API or HTML site for example
<FromGitter> <j8r> A case/when can be done inside
<FromGitter> <Blacksmoke16> 👍 fair enough
<FromGitter> <j8r> By default, all exception returns `500`
<FromGitter> <j8r> And the router ones bad request
<FromGitter> <Blacksmoke16> not 404?
<FromGitter> <Blacksmoke16> and yea, that works well. is what i did too
<FromGitter> <j8r> There is a handler for 404 – which I may change
<FromGitter> <j8r> But I think it may be useful for a custom 404 page
<FromGitter> <j8r> If the user wants
<FromGitter> <Blacksmoke16> yea for sure, would depend if you making a site or api
<FromGitter> <j8r> Right
<FromGitter> <j8r> I could remove it I guess
<FromGitter> <j8r> It would be simpler
<FromGitter> <Blacksmoke16> simpler isnt always better
<FromGitter> <j8r> Instead of calling the handler, creating an Exception to be handled. But this means having an error logged
<FromGitter> <j8r> How does others do?
<FromGitter> <j8r> For not found handling
<FromGitter> <Blacksmoke16> by default i just JSON serialize the exception
<FromGitter> <j8r> So it's an exception?
<FromGitter> <Blacksmoke16> yea, which would then be ran thru a https://athena-framework.github.io/athena/Athena/Routing/ErrorRendererInterface.html
<FromGitter> <j8r> I will remove thr not found handler, and just create an Exception without raising
<FromGitter> <j8r> Thanks
<FromGitter> <j8r> That was I thought others do
<FromGitter> <Blacksmoke16> are deff multiple ways to handle it, depends on what your goals are i guess
<FromGitter> <j8r> It would be ok :)
<FromGitter> <j8r> They are both global handlers
<FromGitter> <j8r> Hum actually not
<FromGitter> <j8r> Not Found can't be attached to a controller, obviously
<FromGitter> <Blacksmoke16> well to be fair, not found can be used for more than just routing
<FromGitter> <Blacksmoke16> i.e. `GET /user/1111111` => `404 User with that ID could not be found`
<FromGitter> <j8r> Yes, I mean when a route is not found
<FromGitter> <j8r> That's just a code at the end
<FromGitter> <j8r> Sure
<FromGitter> <j8r> I think there is no way to create a new hash each time to extend a generic union :|
<FromGitter> <j8r> No other way I meant
<FromGitter> <Blacksmoke16> can you not make the hash like `Hash(String, Node)` or something?
<FromGitter> <Blacksmoke16> im not following where the union is coming from, could have a parent controller type or module or something to type things as
ur5us has joined #crystal-lang
<FromGitter> <j8r> I comes from the return type of the Proc
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <Blacksmoke16> what does that have to do with routing tho?
ur5us has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> if the value is `Node(Action(T))`
<FromGitter> <j8r> Yes, it is a generic
<FromGitter> <j8r> For example
<FromGitter> <Blacksmoke16> and cant just type the hash as like `String, Node`?
<FromGitter> <j8r> I don't think so
<FromGitter> <Blacksmoke16> fwiw my `Route` thing has a parent type `Action` that is just used for typing stuff
<FromGitter> <j8r> `Hash(String, Node(Action(String))`, and to include `Node(Action(Bool))`
<FromGitter> <Blacksmoke16> so my radix tree type is like `Radix::Tree(Action).new`
<FromGitter> <Blacksmoke16> id just try that, should help
<FromGitter> <j8r> Is `Action` a generic?
<FromGitter> <Blacksmoke16> no
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4898bd25f1d250fedbdfbd]
<FromGitter> <Blacksmoke16> a module would also work :shrug:
<FromGitter> <j8r> Ho, ol!
<FromGitter> <j8r> Ok!
<FromGitter> <j8r> Neat
<FromGitter> <j8r> I think it will work
<FromGitter> <Blacksmoke16> yea, ideally imo you should be able to do `Route` and it just work for any instantiation of `Route` but :shrug:
<FromGitter> <Blacksmoke16> we can hope :p
<FromGitter> <Blacksmoke16> nice!
<FromGitter> <j8r> What was your workarouns for splat proc?
<FromGitter> <j8r> (Sorry on mobile)
<FromGitter> <Blacksmoke16> manually pass in the `Proc` type itself
<FromGitter> <Blacksmoke16> i.e. `Route(ControllerType, Proc(..., ReturnType))` versus `Route(ControllerType, ReturnType, Int32, String)`
<FromGitter> <Blacksmoke16> how are you handling the arguments to the proc?
<FromGitter> <j8r> For now there is a `Parameters` object
<FromGitter> <Blacksmoke16> which gets setup at compile time? like `action.call params.arg1, ...`?
<FromGitter> <j8r> its `action.call params, context` – no auto setup :/
<FromGitter> <Blacksmoke16> ah
<FromGitter> <j8r> It can be done if we fully type the proc
<FromGitter> <j8r> It may be possible, i will dig
<FromGitter> <Blacksmoke16> one tip i did for athena
<FromGitter> <Blacksmoke16> splat generics like `*Args` supplies them as a `Tuple`
<FromGitter> <Blacksmoke16> so if you provide your arguments as an array, you can do like `Args.from arr`
<FromGitter> <Blacksmoke16> convert the array into a tuple and splat it
ur5us has joined #crystal-lang
ur5us has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 248 seconds]
ur5us has joined #crystal-lang
ur5us has quit [Client Quit]
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
alexherbo2 has joined #crystal-lang
postmodern has joined #crystal-lang
<postmodern> so how does one use a Reference to allocate a C Struct on the heap, so it can be passed by reference?
<FromGitter> <watzon> Well you can use a Pointer, idk if that's what you're wanting though
alexherbo2 has quit [Ping timeout: 272 seconds]
<FromGitter> <confact> Had fun with Git Blobs and porting Github's linguist to crystal: https://github.com/microgit-com/linguist.cr
ur5us has joined #crystal-lang
<postmodern> hmm pointerto is indeed not what i'm looking for. any changes to the struct wrapped in the class aren't persisting
ur5us has quit [Ping timeout: 240 seconds]
postmodern has quit [Quit: Leaving]
postmodern has joined #crystal-lang
<postmodern> is there a way to define a type that's just a restricted set of numbers, but without defining an enum and having to pass around elements from that enum?
<postmodern> like say i have a method that should only accept 16, 32, 64. What's the simplest way to implement that?
<jhass> I don't think there is
<jhass> you could make a macro that validates the value before passing it on
<jhass> that only works if you ever call with literals though (or constants pointing to literals if you throw in a resolve)
<jhass> postmodern: oh and https://crystal-lang.org/api/0.33.0/Box.html is a cheap way to throw a struct onto the heap
<postmodern> jhass, are there examples of how to use Box?
<jhass> well the API is pretty minimal, Box.box(your_struct) gives you a pointer. I guess the gotcha is that the pointer is pointing to a Box wrapping your struct rather than the struct directly. So it's only good for passing to C land if the library treats it as an opaque pointer
<jhass> I guess you could hack yourself a pointer to the struct with box = Box.box(my_struct); ptr = pointerof(box.@object)
<jhass> er, .new rather than .box
<jhass> it's really not much
<jhass> just a generic class to hold something and given it's a class, it's on the heap
<jhass> just if you go with above hack you need to make sure to keep a reference to the box for the GC not to collect it
<postmodern> hmm that doesn't seem like what i want
<postmodern> need to both pass a persistent struct to C, allow it to be modified by C land, then inspect the changes, rinse & repeat
<jhass> mh, I would expect it to be suitable. Maybe not the cleanest but...
<jhass> so the call site to C land has to return inbetween?
<jhass> mh
<jhass> well I think if you'd just wrap your C calls into a class that also holds the struct it should be fine no?
<jhass> something like class Thingie; @data = LibThingie::Data.new; def pass; LibThingie.pass(pointerof(@data)); end; def inspect; @data.foo; end; end;
<jhass> important bit being a class and not a struct
<jhass> then just make sure to have one global, or whatever its lifetime is, reference to your instance of Thingie
<jhass> if that doesn't work I'd rather double check my struct is big enough / defined correctly in general
<jhass> lots of C libs I've seen do some typedef wizardy to add some padding for library internal/private data
<jhass> and then the Crystal allocated struct might not account for that causing the library to access uninitialized/garbage memory
<postmodern> jhass, yeah it's libudis86, where you typically allocate the UD struct on the stack, pass in a pointer. you also set callbacks which passes the same pointer back to your callback. http://udis86.sourceforge.net/manual/libudis86.html
<jhass> well that should be as simple as fun ud_init(out obj : UdT)
<postmodern> i'm using pointerof(@struct) in the class, but changes are not persisting when i check the fields of the struct
<postmodern> out and pointerof are the same yes?
<jhass> oh wait I've been using it wrong :D
<jhass> essentially
<jhass> so fun ud_init(obj : UdT*); and call it with C.ud_init(out obj); obj = ...
<jhass> do you have some example code of what you're trying maybe?
<jhass> eh, sorry, tired, that ob = ... was meant as obj.foo of course
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
<postmodern> i could try to git push what i have so far
<jhass> ah sorry, out is only good for the init call, pointerof was correct for the others (or any in this example)
<jhass> let me see
<jhass> yeah that ud struct seems like some work to map correctly
<postmodern> jhass, added my LibUDis86::UD struct https://gist.github.com/postmodern/930b6a8041719e9cb0f8fdb6b9058d02
<postmodern> the C API doesn't provide ud_get functions, so to inspect the current state you have to access the struct fields directly
<jhass> mh, operand is ud_operand[3] in my header
<jhass> but that's after pc so it shouldn't garble that one
<jhass> however asm_buf_int is char[128] for me
<jhass> maybe that's it?
<postmodern> jhass, updated to add ud_operand and friends
<postmodern> fields like pc, vendor, and dis_mode are good candidates for accessing after you call ud_set_pc, ud_set_vendor, ud_set_mode
<FromGitter> <j8r> @Blacksmoke16 Thanks. Yes, I did for the splat, then pass the args to the method/proc
<jhass> do you have __UD_STANDALONE__ set?
<jhass> for me it was that
<jhass> postmodern: https://p.jhass.eu/7k.cr this quick and dirty does what I expect it to
<postmodern> jhass, from what i can tell, __UD_STANDALONE__ is an optional -D that gets passed in. it should be off by default.
<jhass> well I tried without and got 16 out of pc, with it I got 0 & 23 as expected
<jhass> note that the __UD_STANDALONE__ is a compile time setting of the .so you link against
<jhass> also note the difference in asm_buf_int that we have
<postmodern> jhass, hmm still getting 0 after wrapping everything in pointerof()
<jhass> those are the two factors I see that could make your pc offset wrong
<postmodern> hmm good point
<jhass> could be version differences, I don't know
<jhass> I just installed whatever I found in the AUR
<jhass> btw are you even supposed to access those fields in regular usage or is the struct meant to be opaque?
<jhass> I don't remember whether the typedef ud_t struct ud; hides the fields in C land
<postmodern> with it hardcoded enabled and disabled, i still get 0
<jhass> can you gist your libudis86/types.h?
<postmodern> the struct is exposed via the headers so i'm assuming they are public. the author started adding _ prefixes to certain fields to denote privateness
<jhass> oh my insn_offset also is a UInt64 instead of a UInt16
<postmodern> jhass, added types.cr
<jhass> haha, I meant the actual types.h you translated from :)
<postmodern> ok added both types.h and extern.h
<jhass> so it's the same as mine
<jhass> try correcting insn_offset to UInt64 :)
<postmodern> did that and still getting 0
<jhass> huh, with & without inp_file?
<jhass> and you did correct asm_buff_int too right?
<postmodern> both
<postmodern> aaah getting back 16, but that's not exactly the same as 0x400000
<postmodern> should contain that value since pc is UInt64
<jhass> 16 I got when I had inp_file missing 🤔
<jhass> so of by a 4 bytes I guess?
<jhass> btw I had a mistake too, made asm_buf LibC::Char instead of LibC::Char*, just turned out to be alright due to same size :D
<postmodern> 0x400000 >> 18 just so happens to be 16
<jhass> well the lib isn't doing that to it https://github.com/vmt/udis86/blob/master/libudis86/udis86.c#L123
<postmodern> do C structs have a size method i could check and compare against C's sizeof(struct ud)?
<jhass> yes, just sizeof(LibUD::UD)!
<jhass> there's offsetof too, so you can start to bisect
<jhass> anyway, I'm unable to spot further differences :/
<postmodern> hmm 592 doesn't look right, considering C says 632. Also having issues with my ruby FFI implementation giving me 600 bytes... :/
<postmodern> i'm assuming crystal's sizeof accounts for alignment/padding?
<jhass> I hope so, I think it just wraps the LLVM IR primitive
<jhass> my offsetof(LibUd::UD, @pc) is 376 fwiw
Nicolab has joined #crystal-lang
<postmodern> jhass, oh could I use the awesome Hexdump module in stdlib to just dump the bytes of the struct out and see if they are even getting set, or misaligned?
<jhass> that ought to be possible somehow
<postmodern> 368 offset in my env :|?
<postmodern> i'm doing this in a VM, so no crazy architectures or byte packing
<jhass> Bytes.new(pointerof(@obj).as(UInt8*), sizeof(LibUd::UD)).hexdump
<jhass> @obj being the struct
<postmodern> holy cow thats cool
<jhass> Bytes is just Slice(UInt8)
<jhass> probably could pass @obj to sizeof too
<jhass> ah no
<jhass> still can do def hexdump(value : T) forall T; Bytes.new(pointerof(value).as(UInt8*), sizeof(T)).hexdump; end to dump anything I think
<jhass> anyways, I'd get the offsetof of each field up to pc in Crystal and C and see where they diverge
<jhass> the one before the first one that mismatches should be too short
<jhass> (or even on missing there)
<jhass> hahah
<jhass> you're actually missing inp_peek!
<jhass> I didn't search for missing fields yet
<jhass> postmodern:^
<jhass> no wait, I'm confused
<jhass> you have it, I don't
<jhass> yet you're too short still?
<jhass> well maybe you're not, just compared to me
<jhass> but then if I have less something else seems to be too short
<jhass> less fields I mean
<jhass> haha, this is confusing
alexherbo2 has joined #crystal-lang
<FromGitter> <636f7374> Fuck, my credit card was stolen yesterday. Fortunately, that credit card didn't have much balance. Today, I want to buy a domain name and find that the balance is insufficient. The little bastard in the Philippines.
<postmodern> jhass, well i wrote two programs to enumate offsetof and they are exactly the same.
<jhass> huh, weird
<jhass> well we certainly discovered some problems there, so it definitely was part of the problem
<jhass> did you try staring at the hexdump yet?
<postmodern> jhass, https://gist.github.com/postmodern/930b6a8041719e9cb0f8fdb6b9058d02#gistcomment-3178641 either offsetof is naive, or corruption is happening
<jhass> well I'm out of ideas then :/
<postmodern> ok working on implementing that hexdump method
<jhass> oh, you're still using out?
<jhass> or just didn't update that part
<postmodern> hmm hexdump isn't printing anything
<postmodern> def hexdump; Bytes.new(pointerof(@ud).as(UInt8*), sizeof(LibUDis86::UD)).hexdump; end
Nicolab has quit [Ping timeout: 260 seconds]
<postmodern> hmm this is weird. copy/pasting an `UInt8.slice(0x1, 0x2, 0x3).hexdump` also fails to output anything. seems like a stdout issue
<postmodern> aaah derp need to puts it...
<postmodern> well i'm not seeing any of the hex characters that i'm setting show up. tried setting pc to 0xfefefefe or 0xdeadface, nothing.
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Client Quit]
<postmodern> also not seeing any difference between before and after hexdumps, which leads me to believe the writes are never happening on the original struct
alexherbo2 has joined #crystal-lang
<jhass> still those (out @ud)'s in your real code?
<jhass> try turning them back into pointerof's
<postmodern> jhass, fully replaced with pointerof, still the same behavior
<jhass> huh
<postmodern> also odd there's a bit of garbage data in the struct at BEFORE and AFTER. This seems to be as ud_init isn't actually writing back to the struct, but a copy, despite passing pointerof()
<jhass> I don't know, it works in my hack script from earlier as I expect
<postmodern> jhass, printing 16 isn't working though, because we're assigning pc to 0x40000
<postmodern> jhass, can you copy/paste my gist and see if that works
<jhass> not sure it's complete enough to actually run?
<postmodern> jhass, what does the compiler say is missing?
<jhass> I didn't have time to try yet, sorry
<jhass> meanwhile I'm curious if https://p.jhass.eu/7l.cr does work for you (after adding the insp_peek that I don't have)
<jhass> with that I do see fefefe at 178
<FromGitter> <wout> Hi all, is there a way for HTTP::Client to use verify_mode = OpenSSL::SSL::VERIFY_PEER with a ca_file, just as Ruby's Net::HTTP?
<FromGitter> <tenebrousedge> https://crystal-lang.org/api/0.24.2/HTTP/Client.html#new%28host%3AString%2Cport%3Dnil%2Ctls%3ABool%7COpenSSL%3A%3ASSL%3A%3AContext%3A%3AClient%3Dfalse%29-class-method
<jhass> UDMnemonicCode is missing from your gist for example
<FromGitter> <tenebrousedge> the last arg can be the ssl context
<FromGitter> <tenebrousedge> https://crystal-lang.org/api/0.24.2/OpenSSL/SSL/Context.html#ca_certificates%3D%28file_path%3AString%29-instance-method
<postmodern> jhass, inp_peek is in my code as well at 187
<jhass> yes but not in mine!
<postmodern> jhass, er ud_struct.cr:20
<jhass> for some reason my headder doesn't have it, I suspect different versions
<postmodern> jhass, i'm using fedora's udis86-devel 1.7.2
<jhass> mh, AUR package is at 1.7.2 too
<jhass> weird
<FromGitter> <j8r> @Blacksmoke16 The `abstract struct Action`didn't work (because of `abstract def` inside), but with a module it did :)
<postmodern> jhass, i can try running it against upstream udis86 linked locally. however i strongly suspect the problem is that the C library isn't writing back to the original struct.
<jhass> well I got your code to run and it's not writing either for me apparently
<jhass> very weird
<postmodern> jhass, Crystal 0.32.1 [41bd18fbe] (2019-12-18) LLVM: 8.0.0 Default target: x86_64-unknown-linux-gnu
<jhass> ooooh
<jhass> I see it
<jhass> value vs pc
<FromGitter> <j8r> https://carc.in/#/r/8kir :(
<jhass> that took way too long to spot :D
<FromGitter> <j8r> `def a(&proc : Proc(T)) forall T` don't work, unfortunately
<FromGitter> <tenebrousedge> https://carc.in/#/r/8kiu
<FromGitter> <j8r> that's what I do currently
<FromGitter> <j8r> but this means on my case having `Controller(T)`, which impose a return type for all routes :(
<FromGitter> <tenebrousedge> it needs some way of knowing that `T` is a free variable
<FromGitter> <j8r> I may have an idea
<jhass> postmodern: got it?
<FromGitter> <j8r> hum no in fact 😅
<postmodern> jhass, well that's embarrassing! maaaaaaan
<FromGitter> <tenebrousedge> do you have to use a proc there? would a struct that wraps the proc be better?
<jhass> postmodern: haha, don't worry, didn't spot it and could've in the first gist :D
<FromGitter> <j8r> @tenebrousedge https://carc.in/#/r/8kix !
<FromGitter> <j8r> @tenebrousedge but then the struct has to old the return type has a generic
<FromGitter> <j8r> like `Action(T)`, with `Proc(T)` inside
<FromGitter> <tenebrousedge> whaaaaaaat
<FromGitter> <tenebrousedge> o______o
<jhass> postmodern: I hope the journey was insightful anyways :D
<jhass> still no clue what's up with that inp_peek but ok
<FromGitter> <Daniel-Worrall> Couldn't you set it as a class method so you don't need to instantiate
<FromGitter> <Daniel-Worrall> Or even as a module? Hmm
<FromGitter> <Daniel-Worrall> Can you have a generic module
<postmodern> jhass, i mean it's technically allowed to call the getter method from within the setter method, and without parenthesis. preventing such an edge case would likely add a ton of annoying rules to the language.
<postmodern> jhass, i'm just happy i can continue working on this library and get it released soon
<jhass> <3
<jhass> and you learned about offsetof, sizeof, out and Box on the way!
<FromGitter> <Blacksmoke16> @j8r yea are some bugs around that. Sometimes inheritance works others a module works
<FromGitter> <Blacksmoke16> i originally used class methods for the actions, then you dont have to worry about newing up the controller, but ofc DI doesnt work then; which if you dont care about could be a solution
<FromGitter> <wout> @tenebrousedge Great, thanks! Works liek a charm. :)
<FromGitter> <tenebrousedge> np 👍
<FromGitter> <j8r> got it @tenebrousedge : https://carc.in/#/r/8kj4
<FromGitter> <tenebrousedge> huh
<FromGitter> <j8r> @Blacksmoke16 I think I will do that for the `Result` (post action) handler, `forall T` isn't enough
<FromGitter> <Blacksmoke16> 👍 `forall T` prob wouldnt work if you had to set it as an ivar
<FromGitter> <Blacksmoke16> how would you do the ⏎ ⏎ ```if var = @some_ivar``` [https://gitter.im/crystal-lang/crystal?at=5e4950420d257250fdee0836]
<FromGitter> <Blacksmoke16> how would you do the ⏎ ⏎ ```if var = @some_ivar ⏎ end``` ⏎ ⏎ if `@some_ivar` is `Bool?`? [https://gitter.im/crystal-lang/crystal?at=5e4950520d257250fdee085b]
<FromGitter> <Blacksmoke16> maybe try
<FromGitter> <j8r> now I have this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4950750c50da598c140ba6]
<FromGitter> <j8r> doesn't work, it complains that `String#to_json` doesn't exist
<FromGitter> <j8r> perhaps changing like you said to `self.call`
<FromGitter> <636f7374> if var = @some_ivar ⏎ end = `unless nil?`
<FromGitter> <j8r> the class is jsut declared - not used
<FromGitter> <Blacksmoke16> did you `require "json"`?
<FromGitter> <j8r> ha... lol
<FromGitter> <636f7374> include `JSON::Serializable`?
<FromGitter> <j8r> so obvious, thanks 😅
<FromGitter> <j8r> but that's strange
<FromGitter> <j8r> I didn't even instantiate the class
<FromGitter> <j8r> yeah everything compiles and the few dumb specs pass
<FromGitter> <j8r> One cool thing is detection of conflicting routes
<FromGitter> <j8r> if there is `get "/public/api"` and `get "public/{user}"` - raises at startup
<FromGitter> <Blacksmoke16> \o/
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8kj8 if anyone has any ideas 😐
<FromGitter> <Blacksmoke16> trying to reduce it further
<FromGitter> <Blacksmoke16> something within the `#resolve` method the compiler doesnt like
<FromGitter> <Blacksmoke16> but i dont know why its complaining since there isnt any type restrictions for it to complain about
<FromGitter> <asterite> compiler bug related to caching, probably generics
<FromGitter> <Blacksmoke16> ill make an issue
postmodern has quit [Quit: Leaving]
<FromGitter> <Blacksmoke16> actually this is interesting, it compiles when using a module, but then `Int32?` param type is used twice https://play.crystal-lang.org/#/r/8kjb
<FromGitter> <Blacksmoke16> so it doesn't go thru the correct `from_parameter` method
<FromGitter> <Blacksmoke16> i imagine those are two separate issues?
HumanGeek has quit [Remote host closed the connection]
HumanGeek has joined #crystal-lang
<FromGitter> <asterite> I think it's a bug related to subclasses of modules or generic types affecting methods that were already typed
<FromGitter> <asterite> reporting it as two issues or one is similar
<FromGitter> <Blacksmoke16> I'll put them in one then for now. can always split one out if a fix fixes one but not the other
<FromGitter> <Blacksmoke16> feel free to change the title
<FromGitter> <Blacksmoke16> also came across https://play.crystal-lang.org/#/r/8kjl
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8kjm reduced a bit more
<FromGitter> <Blacksmoke16> which prob *should* work since the parent is abstract?
<FromGitter> <asterite> abstract types must have everything initialized in their constructors
<FromGitter> <asterite> regardless of their subtypes
<FromGitter> <Blacksmoke16> ah right, makes sense
<FromGitter> <636f7374> 1) 33 has been released? I haven't even noticed that I am now testing.
<FromGitter> <j8r> Alpine will drop aarch64 to bump to Crystal 0.33
sagax has quit [Remote host closed the connection]
sagax has joined #crystal-lang
<FromGitter> <tenebrousedge> ```code paste, see link``` ⏎ ⏎ The error in the second case is that @a is used before it is defined, rendering it nilable. Is there a particularly good reason for that being an error? [https://gitter.im/crystal-lang/crystal?at=5e4989bdb3023d5025f3e327]
<FromGitter> <j8r> The `@` inside the constructors are a shortcut, it works when done inside the block
<FromGitter> <j8r> Basically, it's reweitten to `@a = a` and `@b = b`
<FromGitter> <j8r> (AFAIK)
<FromGitter> <j8r> works ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e4991b718ac9b0fb5c3db1c]
<FromGitter> <tenebrousedge> that's fine, but I think that it should work the way I wrote it
<FromGitter> <j8r> there was a talk for maybe removing the `@` syntax
<FromGitter> <j8r> because there are some corner cases like taht
* FromGitter * tenebrousedge sighs
<FromGitter> <tenebrousedge> of course there was
<FromGitter> <tenebrousedge> ah! now this is a good reason
<FromGitter> <tenebrousedge> > This is because any method call could potentially affect that instance variable, rendering it nil. Another reason is that another thread could change that instance variable after checking the condition.
_ht has quit [Ping timeout: 272 seconds]
_ht has joined #crystal-lang
<FromGitter> <watzon> What would be an alternative to the `@` syntax?
<FromGitter> <tenebrousedge> 🍦 syntax. Everyone likes ice cream
<FromGitter> <wout> Is there an equivalent of Ruby's `assert_raise` in Crystal?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Spec/Expectations.html#expect_raises(klass:T.class,message=nil,file=__FILE__,line=__LINE__,&)forallT-instance-method
<FromGitter> <wout> Thanks!
<FromGitter> <j8r> @watzon I mean inside the `initialize` arguments
<FromGitter> <watzon> Ohhh
<FromGitter> <watzon> Noooo
<FromGitter> <watzon> I like that syntax
<FromGitter> <636f7374> llvm installation is too slow and painful.
<FromGitter> <636f7374> Still installing crystal 0.33 (llvm)
ur5us has joined #crystal-lang
_ht has quit [Quit: _ht]
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8klr any way to use `try` to return a value early within another block?
<FromGitter> <Blacksmoke16> i guess the try isnt needed and you could just do `next d.default unless d.default.nil?`
<FromGitter> <j8r> what's the difference of `next default` instead of `next`
<FromGitter> <j8r> the return type of the block?
<FromGitter> <Blacksmoke16> well in the real code i only want to do the next if its not nil
<FromGitter> <Blacksmoke16> `next param.default unless param.default.nil?` is what i ended up with
<FromGitter> <636f7374> `unless `, `.nil?`?
<FromGitter> <Blacksmoke16> what about it?
<FromGitter> <watzon> `unless` is the opposite of `if`, and `.nil?` checks if a type is `nil`
<FromGitter> <636f7374> `next param.default unless param.default`
<FromGitter> <Blacksmoke16> what if the default is `false`
<FromGitter> <watzon> ^ better to be more explicit
<FromGitter> <watzon> Unless you want to check for any nilable type
<FromGitter> <636f7374> I thought you need to exclude all
<FromGitter> <Blacksmoke16> it should run for all values *except* nil
<FromGitter> <636f7374> `next if nil`
<FromGitter> <636f7374> In the end, crystal 0.33 was finally installed, and I was going to bed.
<FromGitter> <j8r> next if not nil, `next if !default`?
<FromGitter> <j8r> or `!default.nil?`
<FromGitter> <watzon> Yeah, in which case it's more idiomatic to use `unless` I think
<FromGitter> <Blacksmoke16> which would be the same as `unless pram.default.nil?` tho?
<FromGitter> <watzon> I've seen people that hate `unless` though, so whatever floats ones boat
<FromGitter> <j8r> yes, I prefer to avoid it if there is just a bang
<FromGitter> <j8r> because I see sometimes `unles x != y`, and `if x == y`
<FromGitter> <Blacksmoke16> i use whatever reads better, or switch to `if` if the expression has `||` or `&&` in it
<FromGitter> <636f7374> Use whatever you like, this is the best.
<FromGitter> <j8r> simpler for me to always use the same everywhere, and not add another keyword
<FromGitter> <636f7374> Some arithmetic operators are harder to choose
<FromGitter> <636f7374> I will add a suffix to each number, that is, it is int32.
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e49aa58b401eb68a57ffc6e]
<FromGitter> <watzon> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e49ab30b3023d5025f42b22]
<FromGitter> <watzon> Hehe
<FromGitter> <Blacksmoke16> what took you guys so long :S
<FromGitter> <Blacksmoke16> `sudo snap refresh crystal`
<FromGitter> <tenebrousedge> asdf is nice
<FromGitter> <Blacksmoke16> `sudo snap refresh crystal --edge`
<FromGitter> <Blacksmoke16> 😉
<FromGitter> <j8r> I just compile it statically :)
<FromGitter> <watzon> I like asdf. It works and it's fast.
Human_G33k has joined #crystal-lang
HumanGeek has quit [Ping timeout: 272 seconds]
ur5us has quit [Ping timeout: 240 seconds]