jhass changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.28.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
azuri5 has quit [Quit: azuri5]
<FromGitter> <dscottboggs_gitlab> Is there any way besides `!!` to convert to a boolean?
<FromGitter> <Blacksmoke16> neg
<FromGitter> <dscottboggs_gitlab> I don't like that
<FromGitter> <Blacksmoke16> define a method on object like `to_bool` that returns `!!self`?
<FromGitter> <dscottboggs_gitlab> I feel that `!` for `not` is pretty unintuitive to inexperienced programmers. I think there should be an `Object#to_bool` that returns true, and is overridden by `Bool` and `Nil` types.
<FromGitter> <Blacksmoke16> was an issue about this
<FromGitter> <dscottboggs_gitlab> damn it :(
<FromGitter> <dscottboggs_gitlab> yeah I found it
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
alexherbo2 has joined #crystal-lang
alexherbo26 has joined #crystal-lang
<FromGitter> <watzon> Where `!` for `not` may be unintuitive to inexperienced programmers it is a pretty universal concept and definitely something that should be learned
alexherbo29509 has quit [Ping timeout: 250 seconds]
alexherbo26 has quit [Client Quit]
alexherbo26 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo268 has joined #crystal-lang
alexherbo268 has quit [Client Quit]
alexherbo268 has joined #crystal-lang
alexherbo26 has quit [Ping timeout: 250 seconds]
alexherbo2688 has joined #crystal-lang
alexherbo2688 has quit [Client Quit]
alexherbo2688 has joined #crystal-lang
alexherbo268 has quit [Ping timeout: 252 seconds]
alexherbo26886 has joined #crystal-lang
alexherbo2688 has quit [Ping timeout: 252 seconds]
alexherbo268866 has joined #crystal-lang
alexherbo26886 has quit [Ping timeout: 246 seconds]
alexherbo2688667 has joined #crystal-lang
porg has joined #crystal-lang
alexherbo268866 has quit [Ping timeout: 246 seconds]
alexherbo2688667 has quit [Ping timeout: 250 seconds]
porg has quit [Ping timeout: 250 seconds]
f1refly has quit [Ping timeout: 264 seconds]
f1refly has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<FromGitter> <watzon> Is it possible to make a value a Tuple of a known type but unknown size? Like `a : Tuple(Int32*) = {1, 2, 3, 4, 5}`
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 250 seconds]
rohitpaulk has joined #crystal-lang
ian_0xF has joined #crystal-lang
ian_0xF has quit [Client Quit]
rohitpaulk has quit [Ping timeout: 248 seconds]
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 258 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
azuri5 has joined #crystal-lang
rohitpaulk has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
rohitpaulk has quit [Remote host closed the connection]
<FromGitter> <vladfaust> @watzon you could define a splat method for this https://carc.in/#/r/6ued
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
<FromGitter> <watzon> What I need is to be able to do this though ⏎ ⏎ ```def initialize(shape : Tuple(*Int32)) ⏎ end``` ⏎ ⏎ Where `shape` is a Tuple of unknown size but known type. [https://gitter.im/crystal-lang/crystal?at=5cce879eb4700e023d24b7bc]
<FromGitter> <watzon> I can just do `Tuple`, but then it could be a Tuple of any type
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
azuri5 has quit [Ping timeout: 248 seconds]
<FromGitter> <vladfaust> You can't have unknown size tuples as instance/class variables indeed
<FromGitter> <vladfaust> But if it's not a variable, then there is no problem -- https://carc.in/#/r/6ueg
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter> <bew> If you ned ivars with "unknown tuple size" it could be done with generics i think
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
DTZUZO has quit [Ping timeout: 250 seconds]
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
<FromGitter> <mwlang> struggling with my first macro definition. I'm trying to write a method that can obtain it's values from a given source which is just a getter on some class or struct for a Float64 value.
return0e_ has quit [Ping timeout: 248 seconds]
return0e has joined #crystal-lang
<FromGitter> <mwlang> but it expands quite literally to: @points.prev(0).source
<FromGitter> <mwlang> {{source}} is not interpolated.
<FromGitter> <mwlang> a calling example would be: "weighted_average :input_value" and I would've expected "@points.prev(0).input_value" as the result of the macro on line #10 of the gist
<FromGitter> <lsymonds> Hi all. Found and played with Crystal a few days ago and loving it. Looking forward to becoming an active member of the community.
<FromGitter> <dscottboggs_gitlab> @mwlang sorry I was going to reply earlier but I had to go out
<FromGitter> <dscottboggs_gitlab> Your issue is that `weighted_average` needs to be a macro as well, like this
<FromGitter> <dscottboggs_gitlab> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cced7e6a4ef0974715281b0]
<FromGitter> <dscottboggs_gitlab> @lsymonds nice to meet you :)
<FromGitter> <mwlang> @dscottboggs_gitlab Interesting resolution. would not have thought of that.
<FromGitter> <dscottboggs_gitlab> it's ok, macros are a super tough concept
<FromGitter> <mwlang> why does that make it work? what did I miss?
<FromGitter> <mwlang> or maybe better question, why not just change original macro to use {{source.id}} ?
<FromGitter> <dscottboggs_gitlab> well, in the method version of `weighted_average` you assigned a symbol to a varibale named `source`, then passed *that* into a macro. The value of the variable isn't important, it's literal text is. So the macro got a `MacroID` with the text "source" not the text defined by the symbol
<FromGitter> <dscottboggs_gitlab> So you're just moving weighted_average into "macro-land" so that you can figure out what the `MacroID` `source` refers to is
<FromGitter> <dscottboggs_gitlab> does that make sense?
<FromGitter> <mwlang> absolutely!
<FromGitter> <dscottboggs_gitlab> ok good :)
<FromGitter> <mwlang> that was the key thing I was not grokking
<FromGitter> <mwlang> ok, simplified the whole thing... ditched "prev_value" macro and just made it all work directly in the new weighted_average macro.
<FromGitter> <dscottboggs_gitlab> yup that's what I would've done too
<FromGitter> <mwlang> nice how this still feels relatively like Ruby metaprogramming.
<FromGitter> <mwlang> converting a few more similar helper methods in Ruby over to crystal and they're all converting to macros very easily now.
<FromGitter> <dscottboggs_gitlab> wow that's really good to hear
<FromGitter> <dscottboggs_gitlab> it won't work in every case
<FromGitter> <dscottboggs_gitlab> ruby metaprogramming can happen at runtime, macros cannot
<FromGitter> <dscottboggs_gitlab> I.E. you can't take user input then call that string as a method on an object
<FromGitter> <mwlang> yeah, I get that one. I've got a few of those to come...not quite sure how I will refactor those.
<FromGitter> <mwlang> doing the easier stuff first to build my basic familiarity with crystal.
<FromGitter> <dscottboggs_gitlab> There is a way to technically do it, but I would try to use a hash before resorting to that
<FromGitter> <dscottboggs_gitlab> yeah crystal is nice but it's a bit of a "kitchen-sink" language
<FromGitter> <mwlang> how so, kitchen-sink? I mean, I get that it has ability to expose unsafe things like pointers and interact at traditionally "C" level and it takes inspiration from a number of languages, not just Ruby, but it feels pretty cohesive and well thought out to me so far.
<FromGitter> <dscottboggs_gitlab> I just meant that there are a lot of features in the standard library. If you're coming from Ruby, the syntax makes a lot of sense, but if you're coming from no experience there are a lot of things to learn.
<FromGitter> <dscottboggs_gitlab> it's not a bad thing
<FromGitter> <mwlang> oh, I see.
<FromGitter> <j8r> That's quite right, but the learning curve isn't steep
<FromGitter> <mwlang> I can definitely see why a Ruby background makes a transition to Crystal very easy.
<FromGitter> <dscottboggs_gitlab> true! :)
<FromGitter> <dscottboggs_gitlab> good morning @j8r
<FromGitter> <j8r> good evening @dscottboggs_gitlab
<FromGitter> <dscottboggs_gitlab> haha
<FromGitter> <j8r> compared to Rust or C++, Crystal is definitely simpler with less features
<FromGitter> <j8r> but C and Go are simpler
<FromGitter> <dscottboggs_gitlab> Really? I haven't gotten the chance to play with rust too much but I got the impression that it was around the same as crystal when it came to stdlib features, maybe a little less
<FromGitter> <dscottboggs_gitlab> or did you mean syntax edge cases?
<FromGitter> <j8r> not really the stdlib
<FromGitter> <j8r> I mean the borrow checker
<FromGitter> <dscottboggs_gitlab> yeah what a syntactical clusterfuck. I love the idea and can't wait to see it iterated on but...jeeze...
<FromGitter> <dscottboggs_gitlab> I was actually thinking the other day, it would be hypothetically possible to build a borrow checker on top of crystal using macros and Pointers
<FromGitter> <dscottboggs_gitlab> like, as a library you could just include
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
alexherbo2 has joined #crystal-lang
* FromGitter * dscottboggs_gitlab wants
<FromGitter> <j8r> @dscottboggs_gitlab y ou may be interested by https://ziglang.org/documentation/master/#Memory
<FromGitter> <j8r> an allocator can be chosen, there is none by default
<FromGitter> <dscottboggs_gitlab> interesting
<FromGitter> <mwlang> ok, I'm missing something obvious. I can see PI is a constant for the Math module, but when I attempt to use it: "Math.PI" => undefined method 'PI' for Math:Module
<FromGitter> <dscottboggs_gitlab> `Math::PI`
Welog has quit [Remote host closed the connection]
<FromGitter> <mwlang> hmmm...so why "Math::PI", but not "Math::cos()" or "Math::tan()" I just blindly changed all the "::" to "."
<FromGitter> <dscottboggs_gitlab> I always assumed that was just borrowed from ruby... idk
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
<FromGitter> <mwlang> Ruby can go either way. Looks like in the docs, Crystal developers considered it syntax inconsistency and removed "::" notation for class level method calls.
<FromGitter> <j8r> `::` are used to separate modules, which are CamelCase
laaron has joined #crystal-lang
<FromGitter> <j8r> and `.` to call a method
<FromGitter> <mwlang> Yeah, that's what I just read....I'm just saying in Ruby, Math::cos() and Math.cos() are acceptable.
<FromGitter> <j8r> good to know...
<FromGitter> <j8r> this syntax is accepted for every class method?
<FromGitter> <mwlang> yes
<FromGitter> <mwlang> Oh, this is interesting: https://github.com/rubocop-hq/ruby-style-guide#syntax
<FromGitter> <Blacksmoke16> php uses `::` as well for static methods/constants
<FromGitter> <mwlang> Ruby style guide discourages using this form, though.
<FromGitter> <mwlang> for me, I like it because it serves as a mental note that I'm in fact calling a class level function
<FromGitter> <mwlang> (which may not always be obvious if the module or class was assigned a variable.
<FromGitter> <j8r> I try https://carc.in/#/r/6ui6
<FromGitter> <mwlang> i.e. foo = Math; foo::cos(25) => 0.9912028118634736
<FromGitter> <mwlang> (in ruby)
<FromGitter> <mwlang> @j8r I'm saying the "::" syntax is accepted for every class in Ruby.
<FromGitter> <mwlang> but obviously, it's a form of invocation that's fallen out of favor with the broader community.
<FromGitter> <j8r> nvm I mess up
<FromGitter> <j8r> https://carc.in/#/r/6uid
<FromGitter> <mwlang> So that evaluates to "A"
<FromGitter> <mwlang> similar to what I did assigning "Math" to "foo" variable.
<FromGitter> <j8r> For generics I prefer `Ab(T)` than `Ab<T>`
<FromGitter> <mwlang> I'll just drop my own stylistic convention and adopt Crystal's. There's obviously some good reasons for doing so since the Ruby community produces pretty well-vetted style guide.
<FromGitter> <mwlang> ugh to Ab<T> Nothing about that makes sense. :-p
DTZUZO has joined #crystal-lang
laaron- has joined #crystal-lang
<FromGitter> <alex-lairan> Hello ! ⏎ ⏎ Why this code don't work ? https://carc.in/#/r/6ujh ⏎ ⏎ Can't we compose modules ? [https://gitter.im/crystal-lang/crystal?at=5ccef0fc8446a6023ecde234]
<FromGitter> <j8r> `Hash(Symbol, Composant)`?
laaron has quit [Ping timeout: 256 seconds]
<FromGitter> <j8r> I suggest you a `NamedTuple`
<FromGitter> <j8r> or `Hash(String...)`
<FromGitter> <j8r> anyway, you have an Union somewhere
<FromGitter> <alex-lairan> Yes, but I want Composant, to be able to only do `.price` on this. ⏎ ⏎ (NamedTuple or Hash is a detail, this is just for an example)
<FromGitter> <j8r> not really
<FromGitter> <j8r> you have to deal with union here
<FromGitter> <j8r> not with NamedTuple
<FromGitter> <j8r> https://carc.in/#/r/6ujp
<FromGitter> <j8r> that's why `Hash(Symbol, T)` isn't a good Ruby habit :P
<FromGitter> <alex-lairan> Ok ;)
<FromGitter> <alex-lairan> Oh, with this : https://carc.in/#/r/6ujr ⏎ I have an Hash (so I can add things later) and no Union (lower compile time)
<FromGitter> <alex-lairan> But it's not elegant
<FromGitter> <j8r> `NamedTuple` is a struct, more efficient than allocation a `Hash`
<FromGitter> <alex-lairan> The problem with union is that if I have a union with 1000 elements, it will create 1000 different methods
<FromGitter> <j8r> the best would be to create your own struct
<FromGitter> <Blacksmoke16> why not just use an array of structs
<FromGitter> <dscottboggs_gitlab> only if you actually call the methods
<FromGitter> <j8r> 💯
<FromGitter> <Blacksmoke16> with a like `type` property
<FromGitter> <Blacksmoke16> make type an enum
<FromGitter> <Blacksmoke16> and could do like `@components.select(&.type.screen?).sum_by { |c| c.price }`
<FromGitter> <Blacksmoke16> with ofc `Component` being abstract struct with common fields
<FromGitter> <alex-lairan> Because I don't want to have multiple screens :) ⏎ ⏎ I'm using an ObjectPool pattern
<FromGitter> <Blacksmoke16> then dont push multiple to the array
<FromGitter> <alex-lairan> If the design allow it, so one day it will be true :(
<FromGitter> <Blacksmoke16> then why not just have like `@screen`, `@processor` properties on `Computer`
<FromGitter> <alex-lairan> A reason why I leaved Ruby, in Crystal we have more power about what we want.
<FromGitter> <Blacksmoke16> and new it up with instances of those types
<FromGitter> <alex-lairan> It could be a thing too ! :)
<FromGitter> <elankvitko> hey everyone :) sorry to be a bother but can you recommend please a good framework to use for creating api’s with jwt support? i was thinking amber or lucky. never used either one so i have a learning curve. would love to know which route i should taker
<FromGitter> <elankvitko> take
<FromGitter> <dscottboggs_gitlab> I have been working on Kemal + JWT auth stuff for a while and recommend it
<FromGitter> <dscottboggs_gitlab> sec
<FromGitter> <elankvitko> Thanks so much!
<FromGitter> <dscottboggs_gitlab> Also, @Blacksmoke16's Athena is super powerful for JSON apis
<FromGitter> <dscottboggs_gitlab> @elankvitko https://github.com/dscottboggs/kemal-jwt-auth
<FromGitter> <Blacksmoke16> https://github.com/Blacksmoke16/athena/tree/master/docs ^ im biased since i made it but still :p
<FromGitter> <Blacksmoke16> check out the docs and just pick one that best suits what you want to do
<FromGitter> <alex-lairan> @elankvitko I'm using Amber and JWT here : https://github.com/easyTeamProject/Backend/ ⏎ ⏎ But a framework is not something very important ;) ⏎ Use the one you love. [https://gitter.im/crystal-lang/crystal?at=5ccef5485b3f941aa5e72e4b]
<FromGitter> <elankvitko> Lol thank you so much and @Blacksmoke16 thanks for all the hard work you put in to make using crystal in the future for so many a reality
<FromGitter> <elankvitko> thanks @alex-lairan i tried amber actually once but was in a rush. i gave up after i couldn’t get associations working
<FromGitter> <elankvitko> got frustrated lol
<FromGitter> <Blacksmoke16> np, but thats prob more credit than i deserve :p
<FromGitter> <elankvitko> Haha i was just at railsconf in minneapolis and was raving about crystal to everyone trying to open their eyes. harder to do than i thought
<FromGitter> <elankvitko> everyone was like it’s not mature and it wont be for another 10 years and probably gonna die out anyway blah blah
<FromGitter> <Blacksmoke16> examples from the blog article i wrote
<FromGitter> <dscottboggs_gitlab> Oh nice! I didn't know you got JWT built in
<FromGitter> <Blacksmoke16> well i mean its not? but the tools are there to do it
<FromGitter> <elankvitko> That’s awesome
<FromGitter> <dscottboggs_gitlab> oh ok
<FromGitter> <Blacksmoke16> then in controllers you can just do `current_user` which would be the user that relates to that jwt token
<FromGitter> <dscottboggs_gitlab> good example at least
<FromGitter> <Blacksmoke16> ye
<FromGitter> <Blacksmoke16> then any controller you want to be authed inherit from `SecurityController`
<FromGitter> <Blacksmoke16> or whatever you call it
<FromGitter> <elankvitko> i’ll definitely be trying this out. can i be annoying with questions? lol
<FromGitter> <Blacksmoke16> sure
<FromGitter> <elankvitko> Thanks!
<FromGitter> <Blacksmoke16> https://dev.to/blacksmoke16/creating-a-json-api-with-athena--granite-510i is the related article, might be helpful as well
<FromGitter> <Blacksmoke16> granite is the same ORM used in amber
<FromGitter> <Blacksmoke16> not a super big fan of the model syntax but is what it is :shrug:
<FromGitter> <elankvitko> oh great. i’ll try it out.
<FromGitter> <Blacksmoke16> when using annotations*
<FromGitter> <elankvitko> haha missing activerecord right about now
<FromGitter> <Blacksmoke16> 😉
<FromGitter> <elankvitko> do you have an idea as to when/if crystal will be ready for production use?
<FromGitter> <Blacksmoke16> its already used in prod in some places
<FromGitter> <dscottboggs_gitlab> mostly web stuff rn
<FromGitter> <elankvitko> I see. Cool i have really high hopes for crystal. im praying every day it gets more recognized
<FromGitter> <Blacksmoke16> we shall see
<FromGitter> <mwlang> I don't much care for ActiveRecord generally speaking. It's a beast under the covers.
<FromGitter> <mwlang> Love Sequel, though.
<FromGitter> <Blacksmoke16> an orm is tricky, esp when you need to support various db
<FromGitter> <mwlang> anything worth porting, Sequel would be the one I'd attempt.
<FromGitter> <mwlang> yeah, an ORM in crystal seems to be like it would be the "Disney world" of a collection of macros.
<FromGitter> <mwlang> esp. for something like an AR port which has so much meta-programming in it, it's not even funny.
<FromGitter> <Blacksmoke16> any orm would have to use macros in some regards
<FromGitter> <Blacksmoke16> some use them in more hacky ways than others thats for sure
<FromGitter> <Blacksmoke16> whether those macros are used with actual `macro` defs or with annotations; either way they are still using macros
<FromGitter> <alex-lairan> @mwlang I tried to create an ORM like ROM https://github.com/alex-lairan/azurite ⏎ ⏎ It's for mongo, it work for simple queries, but it's a POC.
<FromGitter> <Blacksmoke16> does mongo use json for the queries?
<FromGitter> <mwlang> @alex-lairan I was about to say "there's no code there" but the bulk of the work is in another branch other than master.
<FromGitter> <mwlang> might want to merge that or people will not look too far into this project.
<FromGitter> <mwlang> huh? Array doesn't have slice method? (or is that me doing something wrong): "undefined method 'slice' for Array(JSON::Any)"
<FromGitter> <alex-lairan> @mwlang it's a POC, it should not be used ^^
<FromGitter> <Blacksmoke16> can do `to_unsafe` then pass that to `Slice.new`
<FromGitter> <Blacksmoke16> maybe like ` Slice.new(array.to_unsafe, array.size)`?
<FromGitter> <mwlang> @alex-lairan I saw that. Just sayin' :-)
<FromGitter> <elankvitko> @Blacksmoke16 in your tutorial i can’t seem to find where to put the actual sql statements
<FromGitter> <elankvitko> under user model
<FromGitter> <elankvitko> CREATE TABLE "blog"."users"
<FromGitter> <elankvitko> that part
<FromGitter> <Blacksmoke16> https://github.com/Blacksmoke16/athena-blog-tutorial/tree/master/db i just put them under like `db/`
<FromGitter> <Blacksmoke16> and run them directly on the db, there are shards out there to help with migrations
<FromGitter> <elankvitko> i see. thanks
<FromGitter> <elankvitko> which one do you like?
<FromGitter> <Blacksmoke16> for what i do its just easier to run the raw sql
<FromGitter> <Blacksmoke16> i heard good thing about the migrate one tho
<FromGitter> <elankvitko> great. i will check it out
<FromGitter> <Blacksmoke16> np
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #crystal-lang
<FromGitter> <mwlang> Ah...."Ruby's Array#slice really is just an alias for Array#[]. If you look at our Array#[] you'll find it already covers most, if not all, of the same usecases."
<FromGitter> <mwlang> so, bye-bye #slice, hello using brackets everywhere.
<livcd> Was there any Crystal talk at RubyKaigi ?
hightower2 has joined #crystal-lang
olbat[m] is now known as olbat[m][m]
olbat[m][m] is now known as olbat[m]1
olbat[m]1 is now known as olbat[m]2
<FromGitter> <vladfaust> Nope
<FromGitter> <vladfaust> I guess there are no applicants in our community having enough resources to both attend the conf and prepare the talk
<FromGitter> <watzon> Hopefully soon
alexherbo29 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 252 seconds]
alexherbo291 has joined #crystal-lang
alexherbo29 has quit [Ping timeout: 248 seconds]
<FromGitter> <malkomalko> I know of `&.method` shortcut when dealing with `map` etc, but that ends up calling the `method` on whatever type is in the Iterable. Is there any shortcut for passing a function to `map` that's in the same class it's being called from?
<FromGitter> <Blacksmoke16> :thinking:
<FromGitter> <dscottboggs_gitlab> `&->`
<FromGitter> <Blacksmoke16> wait what
<FromGitter> <Blacksmoke16> interesting
<FromGitter> <dscottboggs_gitlab> ```def say_hello ⏎ puts "Hello" ⏎ end ⏎ ⏎ twice &->say_hello``` [https://gitter.im/crystal-lang/crystal?at=5ccf3fb5990feb45185aa6ad]
<FromGitter> <Blacksmoke16> can you pass a param to that method/
<FromGitter> <Blacksmoke16> like the item in map?
<FromGitter> <dscottboggs_gitlab> idk probably with the weird precedence situation as with `&.` but idk I've never used it
<FromGitter> <malkomalko> Let me give it a try
<FromGitter> <malkomalko> Nope. Thanks for telling me about that though, I'm going to add that to my tool belt.
<FromGitter> <alex-lairan> Interesting. ⏎ ⏎ It's possible to transform method into proc ?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6uly @alex-lairan
<FromGitter> <malkomalko> `&->` actually works well if you return a `Proc` from your method call
<FromGitter> <malkomalko> I'm going to roll with that approach
<FromGitter> <Blacksmoke16> @malkomalko got an example of what you are doing?
<FromGitter> <malkomalko> Let me whip one up
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <alex-lairan> @Blacksmoke16 https://play.crystal-lang.org/#/r/6ulz
<FromGitter> <alex-lairan> `->foo` it's just a shortcut for `-> { foo }`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6um5
<FromGitter> <Blacksmoke16> have to also pass type of the args when doing the `->foo`
<FromGitter> <alex-lairan> Oh ! Super !
<FromGitter> <dscottboggs_gitlab> I guess that's why you can't do `->foo(args)`
<FromGitter> <Blacksmoke16> ^ this is how athena handles its route actions btw
<FromGitter> <Blacksmoke16> converts action handlers to procs to call them later
<FromGitter> <Blacksmoke16> and uses https://crystal-lang.org/api/0.28.0/Tuple.html#from%28array%3AArray%29%3Aself-class-method to convert args to a tuple to splat it into the method
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/7698 be aware of this issue tho
<FromGitter> <malkomalko> https://play.crystal-lang.org/#/r/6umh
<FromGitter> <malkomalko> Couldn't figure out how to have `exclaimify` in that example be a method and not a proc, but that's more along the lines of what I was talking about
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6umj
<FromGitter> <dscottboggs_gitlab> whh....
<FromGitter> <dscottboggs_gitlab> ok
<FromGitter> <malkomalko> So you have to pass it the type? That's really weird
<FromGitter> <malkomalko> But I guess that makes sense
<FromGitter> <alex-lairan> Damn, this will help me a lot ! :D ⏎ ⏎ Many times, I create a function like this : ⏎ ⏎ ```def do_x ⏎ ->(...) { ... } ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5ccf449d8446a6023ed017a3]
<FromGitter> <malkomalko> I'm glad I asked this question :D
<FromGitter> <dscottboggs_gitlab> me too :)
<FromGitter> <Blacksmoke16> yea the same idea as to @alex-lairan example
<FromGitter> <Blacksmoke16> but i guess it just knows to pass the item to the method
<FromGitter> <Blacksmoke16> since nothing there specifically does that
<FromGitter> <Blacksmoke16> i wonder
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6uml yup, it just must pass along same args that are in the block
<FromGitter> <Blacksmoke16> neat
<FromGitter> <Blacksmoke16> prob would make for a good PR on the crystal docs
<FromGitter> <malkomalko> Yup. I had no idea and this will clean up a lot of my code
<FromGitter> <Blacksmoke16> @dscottboggs_gitlab https://github.com/Blacksmoke16/athena/tree/custom-settings/docs#custom-settings check this out
<FromGitter> <Blacksmoke16> adding custom settings to athena
<FromGitter> <dscottboggs_gitlab> oh sweet
<FromGitter> <Blacksmoke16> are actual objects so type safe and can have methods and stuff
<FromGitter> <lsymonds> What's the idiomatic way for handling code dependencies in Crystal? I'm used to interfaces and IoC containers, not what is given now. Is it a case of duck-typing with base classes or using modules as pseudo-interfaces instead? ⏎ ⏎ Furthermore, when testing, and when absolutely necessary to override a third party dependency, is the standard to simply use modules to override any external code that contains
<FromGitter> ... behavior that needs to change?
<FromGitter> <dscottboggs_gitlab> > using modules as pseudo-interfaces instead
<FromGitter> <Blacksmoke16> have real interfaces would be cool
<FromGitter> <Blacksmoke16> w/o having to include a module or inherit from a subclass
<FromGitter> <dscottboggs_gitlab> > override any external code that contains behavior that needs to change ⏎ ⏎ yes, the language allows does not discourage reopening classes/structs/modules for the purpose of changing their behavoir
<FromGitter> <lsymonds> > > override any external code that contains behavior that needs to change ⏎ > ⏎ > yes, the language allows and does not discourage reopening classes/structs/modules for the purpose of changing their behavior ⏎ ⏎ Great. Good to know I'm on the right track and not missing something entirely! Thank you. [https://gitter.im/crystal-lang/crystal?at=5ccf4a68e416b84519372886]
<FromGitter> <Blacksmoke16> are the docs on it
<FromGitter> <lsymonds> > https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html#redefining-methods-and-previousdef ⏎ ⏎ Ah, didn't catch this as the sidebar is too narrow for the title. Cheers!
<FromGitter> <lsymonds> Ignore that, the sidebar title doesn't match it anyway :D
<FromGitter> <dscottboggs_gitlab> yes the book is more-front-to back than reference-style
<FromGitter> <straight-shoota> > modules as pseudo-interfaces ⏎ ⏎ Drop the pseudo. Modules are interfaces. They also have different applications, but one of their intents is defining an interface that types can include.
hightower2 has quit [Ping timeout: 245 seconds]
early has quit [Quit: Leaving]
early has joined #crystal-lang
<FromGitter> <watzon> I'm trying to make a method that gets the shape of an array, but this isn't working ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ It's giving me the error `Undefinied method 'shape' for Int32`. Can anyone think of a better way to do this or figure out why my method isn't working? [https://gitter.im/crystal-lang/crystal?at=5ccf6dad1cd0b8307dcbd1e4]
<FromGitter> <Blacksmoke16> `self[0]` is an `Int32`, you're defining `shape` on `Array`
<FromGitter> <Blacksmoke16> what is the expected output from an array like `[1,2,3]`?
<FromGitter> <watzon> I was trying to fix that issue by making sure that `self[0]` is an `Array`, but apparently the compiler doesn't care
<FromGitter> <watzon> `[1, 2, 3]` should return `[3]`
<FromGitter> <Blacksmoke16> and that isnt the same as just doing like `arr.last`?
<FromGitter> <watzon> `[[1, 2], [1, 2]]` should return `[2, 2]`
<FromGitter> <watzon> `[[1, 2], [1, 2], [1, 2]]` should return `[3, 2]`
<FromGitter> <watzon> And I suppose so haha
<FromGitter> <Blacksmoke16> ohh, so like first digit is number of elements in array, then the 2nd is the number of elements per sub array?
<FromGitter> <watzon> Exactly, and it should work for any number of dimensions
<FromGitter> <Blacksmoke16> what if its like `[[1, 2], [1,2,3], [1, 2]]`
<FromGitter> <watzon> Ideally it won't be, but I suppose technically it should get the size of the largest array. So the shape would be `[3, 3]`
<FromGitter> <Blacksmoke16> ok
<FromGitter> <Blacksmoke16> `[1, 2, 3]` is `[3]` because its the last or because its the largest
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6uo3 seems to do it if its the latter
<FromGitter> <Blacksmoke16> i also switched to returning a tuple, seemed more appropriate
<FromGitter> <Blacksmoke16> std lib has a levenshtein module btw as well :P https://crystal-lang.org/api/0.28.0/Levenshtein.html
<FromGitter> <dscottboggs_gitlab> what does that have to do with array shape?
<FromGitter> <Blacksmoke16> /shrug
<FromGitter> <dscottboggs_gitlab> heh
<FromGitter> <Blacksmoke16> i suppose you could deduce what the array was from the tuple
<FromGitter> <Blacksmoke16> i.e. {3, 3} you could know it was a 2d array with 3 elements and 3 items per element
<FromGitter> <Blacksmoke16> prob could even add a method to Tuple to generate a new array from it
<FromGitter> <dscottboggs_gitlab> I don't get why you're using a tuple here over an array
<FromGitter> <dscottboggs_gitlab> A tuple's size must be known at compile time
<FromGitter> <Blacksmoke16> apparently not :p
<FromGitter> <Blacksmoke16> types are known, not size
<FromGitter> <Blacksmoke16> hence why this works
<FromGitter> <Blacksmoke16> it knows it'll be a `Tuple(Int32, Int32)`
<FromGitter> <dscottboggs_gitlab> ..what...? the types at each position must be known... which implies the size
<FromGitter> <Blacksmoke16> yea which in thise case is 2
<FromGitter> <dscottboggs_gitlab> it depends on how the caller handles the data
<FromGitter> <dscottboggs_gitlab> or rather if the dimensions are known at compile time
<FromGitter> <Blacksmoke16> im not dynamically adding data to the tuple
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> so types, and therefore size are known at compile time
<FromGitter> <dscottboggs_gitlab> oh I see
<FromGitter> <Blacksmoke16> ofc you cant add/remove elements from it, but its the better way for returning "static" data like this
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ccf75ef3d78aa6c03efd985]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ccf75f55b3f941aa5ea8685]
<FromGitter> <Blacksmoke16> not *that* big of a diff, but is still over 30% faster