jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <Blacksmoke16> basic querying is done now as well
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f260d5986ad126839e0cd30]
<FromGitter> <Blacksmoke16> debating if it would be worth making some of this more type safe or if that would fit better into its own thing and leave this to just be quick/easy querying
<FromGitter> <Blacksmoke16> ill save that for later, would be doable to have entity specific query builders i think, like ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ :shrug: [https://gitter.im/crystal-lang/crystal?at=5f260e4ee3160e46ba9b29c9]
<FromGitter> <watzon> @chasestory no worries about the delay lol. I'm not on here much right now either.
<FromGitter> <Blacksmoke16> boo :p
<FromGitter> <watzon> Gotta focus on things right now that will actually help me in my new job haha. Unfortunately it's not a Crystal position.
<FromGitter> <Blacksmoke16> :sad: least you got a job, that seems to be a hard thing to come find these days
<FromGitter> <watzon> No fucking kidding. Took way too long.
<FromGitter> <watzon> Yay me! Marionette hit 100 stars.
<FromGitter> <Blacksmoke16> \o/
<FromGitter> <mixflame> congratz
<FromGitter> <Blacksmoke16> ran a little benchmark versus granite
<FromGitter> <Blacksmoke16> granite (without using bulk inserts, even tho thats what you should be using if you need to do this) took ~21s to insert 10k records
<FromGitter> <Blacksmoke16> ```code paste, see link``` ⏎ ⏎ my test took ~2s [https://gitter.im/crystal-lang/crystal?at=5f2614f0b6f7406a74010778]
<FromGitter> <Blacksmoke16> i imagine `Benchmark.memory` would be a good metric to check as well...
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> @watzon you remember what the fix was for the long Codegen (bc+obj) compile times?
<FromGitter> <Blacksmoke16> something with some env var path iirc?
<FromGitter> <Blacksmoke16> or i might be thinking of `linking` step
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f26180710aa4562550ece6a]
<FromGitter> <Blacksmoke16> granite has me beat on memory, might be able to optimize that maybe
<FromGitter> <Blacksmoke16> caching the metadata brought it down to `42256032`, good enough for me for now
sagax has joined #crystal-lang
_whitelogger has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 264 seconds]
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
zorp has quit [Ping timeout: 246 seconds]
sagax has quit [Ping timeout: 246 seconds]
<FromGitter> <Blacksmoke16> how do you guys handle naming your files within namespaces? The style guide says to do like `HTTP::WebSocket is defined in src/http/web_socket.cr.`
<FromGitter> <Blacksmoke16> but say you have like `MyApp::Sequencing::Generators::Interface`, feels kinda strange to call it just `interface.cr`, but also naming it `generator_interface.r` is kinda redundant...
<FromGitter> <watzon> I find there are two different ways to do it. Either call the file `interface.cr`, put it in `src/my_app/sequencing/generators/interface.cr`, and namespace it under `MyApp::Sequencing::Generators::Interface` or call the file `interface_generator.cr`, put it in the same location, and namespace it under `MyApp::Sequencing::InterfaceGenerator`. It really just depends on personal preference.
<FromGitter> <watzon> > @watzon you remember what the fix was for the long Codegen (bc+obj) compile times? ⏎ ⏎ I don't actually
<FromGitter> <Blacksmoke16> no worries
<FromGitter> <Blacksmoke16> yea im leaning towards the former
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
Rounin has quit [Ping timeout: 260 seconds]
zorp has joined #crystal-lang
zorp has quit [Ping timeout: 260 seconds]
Rounin has joined #crystal-lang
sagax has joined #crystal-lang
<FromGitter> <j8r> @Blacksmoke16 How your proposal can be done, about adding a constant to a object through an annotation?
f1reflyylmao has quit [Ping timeout: 240 seconds]
<FromGitter> <benphelps> if I create an alias of String, how would I go about using that to define constants ?
<FromGitter> <benphelps> ```alias ObjectType = String ⏎ INTEGER_OBJ = ObjectType("INTEGER_OBJ")``` ⏎ ⏎ something like this [https://gitter.im/crystal-lang/crystal?at=5f2699f76334d26a7e6c9a5a]
<FromGitter> <benphelps> is there a better way to do this? should I just create my own Struct or something else?
<oprypin> benphelps, u should create a struct yes
<oprypin> alias doesnt do anything
<FromGitter> <benphelps> cool, thank you
<oprypin> benphelps, note: `alias ObjectType = String; INTEGER_OBJ = "INTEGER_OBJ".as(ObjectType)` would be 100% equivalent to writing `INTEGER_OBJ = "INTEGER_OBJ".as(String)`
<FromGitter> <benphelps> yeah, it really doesn't matter, I'm just trying to match the Go implementation this guide gives as close as I can
<FromGitter> <benphelps> and he aliases the String type
<FromGitter> <benphelps> but I guess in Go it's an alias to the primitive "string" type, which doesn't really work here with Crystal
f1refly has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<FromGitter> <j8r> how can I list instance vars for a given type? In the top-level, I would like to do `{{ MyObject.instance_vars }}`
<FromGitter> <Blacksmoke16> @j8r something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f26bc1c86ad126839e24f90]
<FromGitter> <Blacksmoke16> and you cant, has to be in context of a method
<FromGitter> <j8r> to use `@type`, I need to be in the object
<FromGitter> <j8r> But I can't
<FromGitter> <Blacksmoke16> but you have a reference to the type outside of it?
<FromGitter> <Blacksmoke16> then it would be like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f26bcaee3160e46ba9ca7ea]
<FromGitter> <j8r> I can't do this inside a method...
<FromGitter> <Blacksmoke16> does it have to be?
<FromGitter> <j8r> yep, this is something like `format.deserialize string, to: MyObj`
<FromGitter> <j8r> anyway, I have a work-around
<FromGitter> <Blacksmoke16> if you create a type with a generic as `MyObj` you can do this on the class level of that type
<FromGitter> <Blacksmoke16> like for example, ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f26bd35b6f7406a74028e97]
<FromGitter> <Blacksmoke16> then i do all the annotation processing within that class, versus passing everything to the constructor
<FromGitter> <Blacksmoke16> within the initializer itself*
<FromGitter> <j8r> I think I will just not do it
<FromGitter> <j8r> the user can use a helper to do so
<FromGitter> <Blacksmoke16> make an issue about the "annotations on a type/def in docs" if one isnt already
<FromGitter> <j8r> https://carc.in/#/r/9hdw
<FromGitter> <j8r> comments can also be generated in the macro helper ofc
<FromGitter> <Blacksmoke16> yea that would do it
<FromGitter> <benphelps> how would I do a case statement that has a type guarantee like `if .is_a?`
<FromGitter> <Blacksmoke16> ```case my_var ⏎ when One then ... ⏎ when Two then ... ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5f26be8c96bd3446a7cb2547]
<FromGitter> <benphelps> thats what I have and it doesn't seem to do what I want
<FromGitter> <Blacksmoke16> or for exhaustive, use `in` versus `when`
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <Blacksmoke16> but the most specific types first
<FromGitter> <Blacksmoke16> put*
<FromGitter> <Blacksmoke16> mainly the last part of it
<FromGitter> <benphelps> i keep forgetting about order, thank you
sagax has quit [Remote host closed the connection]
<FromGitter> <j8r> I think this will be useful in the stdlib https://carc.in/#/r/9he5
<FromGitter> <j8r> same idea as creating a Tuple from an array, but with no intermediary
<FromGitter> <j8r> ho, I didn't know `Class.cast(value)` exists
<FromGitter> <j8r> that's the opposite of `value.as(Class)`
<FromGitter> <Blacksmoke16> I think value.cast is also a good thing that allows providing the type in a variable
<yxhuvud> j8r: Eh, except for being slightly ok for creating union type tuples, how is it better than simply using the Tuple literal?
zorp has joined #crystal-lang
<FromGitter> <Blacksmoke16> how would you go about using placeholders for a PG `IN` clause?
<FromGitter> <Blacksmoke16> `conn.query_all "select * from users where id IN ($1);", args: [[1, 3, 5]]` # => Unhandled exception: invalid input syntax for integer: "{1,3,5}" (PQ::PQError)`
<FromGitter> <Blacksmoke16> sounds like id have to manually build that out versus using placeholders for this?
sagax has joined #crystal-lang
<FromGitter> <Blacksmoke16> oo, or maybe use a placeholder for each item in the array
<FromGitter> <j8r> yxhuvud: in my case, I don't know what's the tuple
<FromGitter> <j8r> This allows to cast sequential "arbitrary" data to a Tuple.
<FromGitter> <j8r> (more or less)
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9hev
<FromGitter> <Blacksmoke16> would be a neat feature to have i think, have `String#gsub(Regex)` that returns an enumerable/iterable
duane has quit [Ping timeout: 256 seconds]
<oprypin> oh. crystal build --debug is borked? > Module validation failed: Instruction does not dominate all uses!
<FromGitter> <dorianmariefr> I can't seem to fix an error: ⏎ ⏎ ``` abstract class Statement ⏎ class Expression < Statement``` ⏎ ⏎ so it should work as it's a subclass, any idea why it's not working? [https://gitter.im/crystal-lang/crystal?at=5f27155536563560f2bbcddc]
<oprypin> dorianmariefr, `Expression < Statement` but not `Array(Expression) < Array(Statement)`
<oprypin> when creating the array u need to create it as Array(Statement) directly
<oprypin> oh nice
<FromGitter> <dorianmariefr> nice thanks @oprypin and @Blacksmoke16 I just added `of Statement` and it works fine now
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <j8r> @Blacksmoke16 there is yielding block variant
<FromGitter> <Blacksmoke16> Of what?
<FromGitter> <j8r> https://crystal-lang.org/api/master/String.html#gsub(pattern:Regex,&)-instance-method
<FromGitter> <Blacksmoke16> ah, yea this is what i ended up doing
<FromGitter> <Blacksmoke16> ``` idx = 1 ⏎ sql.gsub(/\?/) { "$#{idx}".tap { idx += 1 } }``` [https://gitter.im/crystal-lang/crystal?at=5f271c5e8d82e66252febc2f]
<FromGitter> <j8r> also, for the covariance example, I think using the `of` is not a good solution: what about if I have `MyObject(Foo)`
<FromGitter> <j8r> It could likely be `MyObject(Foo){Bar.new}` if it implements `#add`, would be a more general answer IMHO.
<FromGitter> <Blacksmoke16> not terrible, but `sql.gsub(/\?/).each_with_index { |m, idx| "$#{idx + 1}" }` would be a bit cleaner
<FromGitter> <j8r> why using tap?
<FromGitter> <Blacksmoke16> so the string gets returned versus the index
<FromGitter> <j8r> `idx = 0`, then ` idx += 1; "$#{idx}"`
<FromGitter> <Blacksmoke16> meh
<FromGitter> <Blacksmoke16> either way
<FromGitter> <j8r> simpler :P
<FromGitter> <j8r> don't know, the whole `each_with_index` helper is not that good IMO
<FromGitter> <j8r> declaring a counter is as simple, with not much chars at the end
<FromGitter> <Blacksmoke16> true
<FromGitter> <Blacksmoke16> im not too bothered by it
<FromGitter> <Blacksmoke16> refactored how im generating the metadata for my entities, came up with some new patterns that are working quite well
<FromGitter> <Blacksmoke16> doing like ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ then calling a `build_metadata` class method on that class which handles instantiating the obj and such [https://gitter.im/crystal-lang/crystal?at=5f271f104773811023393beb]
<FromGitter> <Blacksmoke16> like adding the columns to the obj
<FromGitter> <Blacksmoke16> also am instantiating structs from the annotation values, and passing those around thru the `build_metadata` class methods
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f271f6ab9bc40357bb26075]
<FromGitter> <Blacksmoke16> like so
<FromGitter> <Blacksmoke16> versus parsing all the annotation data and calling `.new` directly with all that stuff at compile time, which essentially does the same thing but a lot less readable
<FromGitter> <j8r> wow, that's a lot of arguments
<FromGitter> <Blacksmoke16> yea i have a todo about that... `# TODO: Maybe break these out to share with a type for migrations/generation?` :P
<FromGitter> <Blacksmoke16> they all have defaults/are optional so its not like the user needs to provide all of them, nor will they be working directly with this type anyway
<FromGitter> <j8r> that's still ok though, but you won't have much room like adding twice more
<FromGitter> <Blacksmoke16> not sure what other options i have versus breaking the DDL side of things into their own type and passing that in
<FromGitter> <j8r> what is PK?
<FromGitter> <Blacksmoke16> primary key
<FromGitter> <j8r> and FK would be foreign key?
<FromGitter> <Blacksmoke16> eya
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> still unsure how im going to handle associations
<FromGitter> <Blacksmoke16> like is it possible to instantiate two objects from the same result set?
<FromGitter> <Blacksmoke16> i guess if the columns are selected in order, like one object columns, then another could just keep consuming the same result set
<oprypin> can someone remind me how to append stuff to constants at compile time and then use it
<oprypin> hm this works https://carc.in/#/r/9hid but not when i try it in my program
<FromGitter> <Blacksmoke16> prob have to wrap it in a `macro finished` hook
<oprypin> wait what somehow i forgot to actually push the variable. xD
<FromGitter> <Blacksmoke16> that would do it
<oprypin> hmmmm so i want to make a macro that adds a variable to a module and then refers to it
<oprypin> or more to the point:
<oprypin> i want every invocation of a macro to define some global storage for itself and get transformed into an accessor of that global storage. but the point is that i want the ability to modify that value from elsewhere
<oprypin> broken example https://carc.in/#/r/9hig
<oprypin> cc @Blacksmoke16 🙏
<oprypin> and why is this empty now?? https://carc.in/#/r/9hiw
<FromGitter> <Blacksmoke16> bk, was eating dinner
<FromGitter> <Blacksmoke16> let me catch up
alexherbo2 has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9hjn
<FromGitter> <Blacksmoke16> doesnt seem to work when you call the macro from a method
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9hjp
<FromGitter> <Blacksmoke16> probably because that doesnt happen until runtime so the value wouldnt exist at compile time yet
<oprypin> Blacksmoke16, well no, of course all code exists at compile time :)
<oprypin> i suspect this is because this code effectively gets put into main() and everything happening through there is after even every macro finished
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9hjy seems to be correct
<FromGitter> <Blacksmoke16> notice `0` is printed *after* the `{{pp Vars}}`
<oprypin> Blacksmoke16, when you say "correct" wha do you mean
<oprypin> the thing inside the method is still not considere
<FromGitter> <Blacksmoke16> sorry, that your suspicion was correct
<FromGitter> <Blacksmoke16> that it gets added after macro finished
<oprypin> hm thats so weir
<FromGitter> <Blacksmoke16> What's plan b?
<oprypin> no idea
<oprypin> like i could make sure to call that macro only in "correct" situations but i might not even notice when i break it
<FromGitter> <Blacksmoke16> I'm assuming you want to use the macro in both method and non method contexts?
<oprypin> yea i think so
<FromGitter> <Blacksmoke16> there a different approach you could take?
<oprypin> yea i think so
<FromGitter> <Blacksmoke16> nice
<oprypin> anyway this is a super ad-hoc debug console with the ability to modify variables
<oprypin> for the purpose of tuning them live, without needing to modify-compule-run
<oprypin> i have something, but it's really weird
<oprypin> i think a problem here will be that i still can't iterate over vars to present them usefully
<FromGitter> <Blacksmoke16> :shrug:
<oprypin> slightly expanded https://carc.in/#/r/9hk8
f1refly has quit [Ping timeout: 260 seconds]
f1refly has joined #crystal-lang
_whitelogger has joined #crystal-lang
Human_G33k has quit [Ping timeout: 256 seconds]
<FromGitter> <Blacksmoke16> got custom repositories working
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f274fefb9bc40357bb2cbe6]
<FromGitter> <Blacksmoke16> not a huge fan of the `.as` stuff going on, but its prob fine for now
<FromGitter> <Blacksmoke16> actually i have an idea
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f2750c410aa456255119441]
<FromGitter> <Blacksmoke16> made it generic
<FromGitter> <Blacksmoke16> im happy with that for now