ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.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> <Blacksmoke16> @watzon I made this a thing if you want to try it
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec473630c32623a4b44bc95]
<FromGitter> <watzon> Hey if it will work I'll use it haha
<FromGitter> <Blacksmoke16> seems like it does?
<FromGitter> <watzon> Why is the `of String` necessary?
<FromGitter> <Blacksmoke16> welllll
<FromGitter> <Blacksmoke16> cant use `Tuple` without types
<FromGitter> <Blacksmoke16> and cant splat an array
<FromGitter> <Blacksmoke16> and `.of` doesn't exist on a `TupleLiteral`
<FromGitter> <Blacksmoke16> so I convert the array to a tuple to store it, using `of String` to build out `Tuple(String, String)`
deavmi has quit [Ping timeout: 265 seconds]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec474147da13f3a0ac461dd]
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <watzon> Hmm, so what about requiring a Tuple instead of an Array?
<FromGitter> <watzon> Would that work?
<FromGitter> <Blacksmoke16> i dont know the type of the tuple at compile time to pass to the generic
<FromGitter> <Blacksmoke16> i would know its a tuple, but wouldnt know the types of each item in it
<FromGitter> <Blacksmoke16> less you have an idea?
deavmi has joined #crystal-lang
<FromGitter> <Blacksmoke16> pushed it to the `develop` branch if you want to try it
<FromGitter> <Blacksmoke16> hence the branch name, is still WIP so be aware :P
<FromGitter> <Blacksmoke16> rip
<FromGitter> <Blacksmoke16> `splatting a union (Tuple(Int32 | String, Int32 | String, Int32 | String) | Tuple(String, String)) is not yet supported`
<FromGitter> <Blacksmoke16> wait, why is it a union
<FromGitter> <Blacksmoke16> ah, because there are multiple types here
<FromGitter> <Blacksmoke16> oh wait im an idiot
<FromGitter> <Blacksmoke16> here you go @watzon
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec47bdf7da13f3a0ac47179]
<FromGitter> <Blacksmoke16> better?
<FromGitter> <watzon> Much better
<FromGitter> <watzon> What's with the `-1`?
<FromGitter> <watzon> To get the last value?
<FromGitter> <Blacksmoke16> select last obj in the array 😎
<FromGitter> <Blacksmoke16> can be any standard index value
<FromGitter> <watzon> Noice
<FromGitter> <watzon> Good work
<FromGitter> <Blacksmoke16> i realized i dont need to store this in the property metadata obj
<FromGitter> <Blacksmoke16> as its specific to deserialization
<FromGitter> <Blacksmoke16> so can just grab the tuple from the annotation
<FromGitter> <watzon> Looks like that could use a fix
<FromGitter> <Blacksmoke16> ^ develop branch
<FromGitter> <Blacksmoke16> still finishing up some stuff so havent merged anything into master yet
<FromGitter> <watzon> Ahh it is fixed on develop
<FromGitter> <Blacksmoke16> ye
<FromGitter> <Blacksmoke16> i pushed the changes for that ^, if you want to update
<FromGitter> <watzon> Oh damn, you're using Crystal master aren't you? Haha
<FromGitter> <Blacksmoke16> :0
<FromGitter> <Blacksmoke16> its an easy fix
<FromGitter> <Blacksmoke16> if you just want to edit the lib for now :S
<FromGitter> <watzon> Yeah I think it's just the `case in` stuff
<FromGitter> <Blacksmoke16> yea, within the main file
* FromGitter * Blacksmoke16 is on the cutting edge :S
<FromGitter> <watzon> Oh `RangeLiteral#each` is new as well, huh?
<FromGitter> <Blacksmoke16> ah shit
<FromGitter> <Blacksmoke16> yea...
<FromGitter> <Blacksmoke16> but you shouldnt need that
<FromGitter> <watzon> I'll see if I can install master easily haha
<FromGitter> <Blacksmoke16> afaik i got rid of that in the last commit
<FromGitter> <Blacksmoke16> i noticed this with current shards version, update doesnt actually update the lib
<FromGitter> <Blacksmoke16> idt im using it anywhere else
<FromGitter> <watzon> Yeah I deleted the lib directory and shard.lock and reinstalled
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> is fixed on master iirc, i tested it at some point
<FromGitter> <watzon> This should work right? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec480746773a13b23f02a24]
<FromGitter> <Blacksmoke16> yup
<FromGitter> <watzon> I'm getting `Unhandled exception: Couldn't parse (String | Nil) from '{"english" => "Bulbasaur", "japanese" => "フシギダネ", "chinese" => "妙蛙种子", "french" => "Bulbizarre"}'. (Exception)`
<FromGitter> <watzon> Probably because granite makes the field nillable huh?
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> moment,
<FromGitter> <Blacksmoke16> ah yea, didnt handle nilable fields it seems
<FromGitter> <Blacksmoke16> looking into it
<FromGitter> <watzon> I'll wait haha. Good work though, very quick.
<FromGitter> <Blacksmoke16> actually no, seems to be something with dig
<FromGitter> <Blacksmoke16> ohh
<FromGitter> <Blacksmoke16> since the ivar name was `name`, and there was a key in the json called `name`, it was using that
<FromGitter> <Blacksmoke16> alright, pushed
<FromGitter> <watzon> Yeah! It worked!
<FromGitter> <Blacksmoke16> :metal:
<FromGitter> <Blacksmoke16> depending on what you're doing, if its anything serious might want to wait till an official release. Otherwise prob fine just using latest commit until then
<FromGitter> <watzon> I'll probably be working on this project for a bit, so it's nice to be able to use the develop branch for now
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> Any bugs, issues, questions, etc feel free to ask
<FromGitter> <Blacksmoke16> Given it's in development, plenty of time to change things and such
zorp_ has quit [Ping timeout: 272 seconds]
<FromGitter> <Blacksmoke16> hm, im super confused
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/9322 working on an implementation of this for the fun of it
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec498a30506d43ab193a314]
<FromGitter> <Blacksmoke16> trying to figure out how this is possible when they both use the same `@annotations` ivar :thinking:
<FromGitter> <Blacksmoke16> 😕 how does this make any sense ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec49b702f83c139ef90bc8d]
<FromGitter> <Blacksmoke16> self is different?
<FromGitter> <Blacksmoke16> ohhh, missed a delegate
<FromGitter> <confact> How do I get the path to the directory Crystal runs in. say it runs in `~/project`? Does it exists something similar to Rails `Rails.root`?
<FromGitter> <confact> @Blacksmoke16 seems to be for a process? I was thinking more on the actual crystal program. I want to create cache directory in that directory the crystal code runs in.
<FromGitter> <Blacksmoke16> Mmm, I'm not sure if anything like that exists
<FromGitter> <Blacksmoke16> I'd be curious to know as well
<FromGitter> <confact> Like `Crystal.current`, `Crystal.path` or similar would make sense but can't find it in the docs.
<FromGitter> <confact> @Blacksmoke16 think I found it, `Dir.current`
<FromGitter> <Blacksmoke16> doesnt that assume you're in the root directly already tho?
<FromGitter> <Blacksmoke16> or is that all `Rails.root` is?
<FromGitter> <naqvis> @j8r yeah Alpine seems clean ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec4a7240506d43ab193becd]
<FromGitter> <naqvis> yeah, idea proposed is pretty neat 👍
<FromGitter> <Blacksmoke16> ❤️
<FromGitter> <confact> One of the shards I planned to use is throwing: `Arithmetic overflow (OverflowError)` ⏎ ⏎ I will feel stupid but I have to ask, what does that error mean?
<FromGitter> <Blacksmoke16> `Int32::MAX + 1`
<FromGitter> <Blacksmoke16> a value is larger than its data type can hold
<FromGitter> <confact> @Blacksmoke16 simple answer. love it, I understand Int32::MAX + 1 :)
<FromGitter> <confact> oh, and yeah @Blacksmoke16 - Rails.root is just returning the Root directory of the project.
<FromGitter> <Blacksmoke16> i mean yea i know that, but what happens if you had like
<FromGitter> <Blacksmoke16> `/dev/git/test` structure, and you're currently in `test`, would running `ruby app.rb` give the same result as if you were in `git` and did `ruby test/app.rb`?
<FromGitter> <confact> Yes, that is true. And I think `Dir.current` do that right?
<FromGitter> <Blacksmoke16> I'm not sure
<FromGitter> <Blacksmoke16> let me test it i guess
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec4abaf0506d43ab193c782]
<FromGitter> <Blacksmoke16> doesnt account for it
<FromGitter> <Blacksmoke16> sure `Rails.root` isnt some configuration thing?
<FromGitter> <confact> ah, that's sad. It might be some configuration but I am not sure.
<FromGitter> <confact> @Blacksmoke16 another question. do you know some way to create an array between two dates? Like `[Time.utc(2000,1,1)...Time.utc]`
return0e[m] has joined #crystal-lang
<FromGitter> <confact> Made an hack: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Maybe something to add so you can range between two dates? [https://gitter.im/crystal-lang/crystal?at=5ec4bcff990d343a5f3bcd9e]
_whitelogger has joined #crystal-lang
<FromGitter> <naqvis> @confact ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec4c395e8153a398061c992]
<FromGitter> <watzon> The reason it's not built in is because Time is kind of ambiguous. It's hard to know if you want a day range, an hour range, a minute range, etc etc.
<FromGitter> <watzon> But this is probably the best solution
<FromGitter> <naqvis> ❤️
_ht has joined #crystal-lang
<FromGitter> <bararchy> Using the new Log system, how can I control that a shard using it will only Log on Error while my main logs on Debug? right now it seems to just inherit W/E I configure for my own Log module
<FromGitter> <bararchy> It seems that calling `Module::Log.level` = :info has no effect
HumanG33k has quit [Ping timeout: 265 seconds]
<FromGitter> <bararchy> jhass I did :)
<FromGitter> <bararchy> I might have not understood from it that context
<FromGitter> <bararchy> but I would love to get a hint
<FromGitter> <bararchy> Ok, I think I got what you mean
<FromGitter> <bararchy> I can make `bind` multiple times
<FromGitter> <bararchy> controling the log scope
HumanG33k has joined #crystal-lang
<jhass> yeah
alexherbo2 has joined #crystal-lang
<FromGitter> <confact> @naqvis thanks, it is even bigger but seems to cover most things. Thank you!
<FromGitter> <confact> @watzon would love some way to do ranges with dates/times built-in. Maybe it is something to consider for some future version?
<FromGitter> <naqvis> you can remove those string representation methods will make it more than half in size
HumanG33k has quit [Ping timeout: 256 seconds]
<raz> naqvis: hmm. not sure i understand what you're trying to do there. doesn't Time - Time already give a Time::Span?
<raz> oh!
<raz> range...
<jhass> the issue is what would be the step size?
<raz> perhaps something like #each_day, #each_second, etc. could work?
<jhass> what's that to do with Range?
<raz> i thought that was your question, with `(date_a..date_b).each` being not specific enough about the step size
<raz> sorry if i totally missed the point, only glancing in here over coffee
zorp_ has joined #crystal-lang
HumanG33k has joined #crystal-lang
<FromGitter> <naqvis> raz good to know that community gitter channel is addictive like coffee, utilizing every sip to take a look at channel 😆
<FromGitter> <naqvis> yeah, above snippet was quick response to question regarding ranging over dates
<raz> def my fav coffee-place, always something interesting going on in here :)
<FromGitter> <naqvis> 👍 lol
<FromGitter> <confact> @naqvis it does solve my issue. But it would still be nice to have it built in in Crystal :) Thanks for the help!
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
zorp_ has quit [Ping timeout: 260 seconds]
<FromGitter> <naqvis> other languages also don't provide built-in date range functionality as it does raises questions which Chris and jhass already made like the step size
<FromGitter> <naqvis> though each language provide functionality to come-up with custom solutions
<FromGitter> <naqvis> But for sure if you have good idea/thoughts/proposal, its good to raise a RFC or better PR
<jhass> I wouldn't be too opposed to implementing the Number#to interface with a mandatory step : Time::Span argument
<jhass> on Time
<jhass> so you get start.to(end, step: 1.day)
<FromGitter> <naqvis> that's a nice solution
<FromGitter> <naqvis> did a quick search and I think this is something which is very close to your proposed solution, ⏎ https://stackoverflow.com/questions/19093487/ruby-create-range-of-dates
HumanG33k has quit [Ping timeout: 260 seconds]
<jhass> yeah, I don't think we need a Range::Time or so
<jhass> Time#to should be enough
<jhass> maaybe Time.every(start..end, step: 1.day)
<jhass> so you can store and pass ranges around
<FromGitter> <naqvis> yeah, this is more rubyish
HumanG33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 260 seconds]
<FromGitter> <j8r> Should I add things for the GC https://carc.in/#/r/93wf ?
<FromGitter> <naqvis> why `uninitialized`? isn't value type already created on stack?
<FromGitter> <j8r> I need to create an object without monkey patching it (for out-of-the-box deserialization)
alexherbo2 has quit [Ping timeout: 264 seconds]
<FromGitter> <j8r> I need to do this for classes
<FromGitter> <j8r> Got segfault when using a class :/ https://carc.in/#/r/93wh
<FromGitter> <j8r> *Invalid memory access
<FromGitter> <naqvis> `uninitialized` is going to allocate on stack, so don't think we need any kind of GC handling
<FromGitter> <j8r> Any how to fix the above code?
<FromGitter> <j8r> got it
<FromGitter> <j8r> https://carc.in/#/r/93wl
<FromGitter> <naqvis> yeah, was also looking at Reference implementation
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Client Quit]
rocx has joined #crystal-lang
<FromGitter> <j8r> Now I am thinking how to define how to (de)serialize?
sz0 has joined #crystal-lang
<FromGitter> <naqvis> interesting thing i found is that, if you run that code in `crystal play` it will segfault
<FromGitter> <j8r> ho O.O!
<FromGitter> <naqvis> but run okay with `crystal run`
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec51b9fc6541c05d8ec7042]
<FromGitter> <j8r> looks like it can't print, somehow
<FromGitter> <naqvis> `instance = Point.allocate` causes play to segfault
<FromGitter> <naqvis> you are planning to implement your own json parser?
<FromGitter> <j8r> I was, but now it is more a deserializer/serializer
<FromGitter> <j8r> https://carc.in/#/r/93wn
<FromGitter> <j8r> For now, all objects can be serialized/deserialized - out of the box
<FromGitter> <j8r> I need to fight with macros to add annotations to add logic :(
<FromGitter> <naqvis> out of the box thoughts: ⏎ ⏎ 1) use `JSON.parse` to parse data to hash ⏎ 2) iterate over obj and map fields found in loaded hash [https://gitter.im/crystal-lang/crystal?at=5ec51fb4c6541c05d8ec7a32]
<FromGitter> <naqvis> won't this approach lessen the usage of macro? only step 2 would require to use macro
<FromGitter> <naqvis> just some random thoughts lol
<FromGitter> <j8r> `JSON.parse` is less efficient, and we need to add loads of parsing logic
<FromGitter> <j8r> Here, the serialization/deserialization is on a single line (plus annotations on types)
<FromGitter> <j8r> @Blacksmoke16 Are you there?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/93wx
<FromGitter> <j8r> what kind of initializer argument?
<FromGitter> <Blacksmoke16> how could you account for `@z`?
<FromGitter> <j8r> It would fail
<FromGitter> <Blacksmoke16> right, would need a specific constructor for setting ivars from the deserialization data
<FromGitter> <j8r> Or, having an annotation which define a default value
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <j8r> Anyway, not sure it is very possible to share much deserialization/serialization logic
<FromGitter> <j8r> Have you thought about XML?
<FromGitter> <j8r> Or INI?
<FromGitter> <j8r> Some formats are really special
<FromGitter> <Blacksmoke16> i tested my thing with messagepack
<FromGitter> <Blacksmoke16> worked well, only needed to define like 2 files for it
<FromGitter> <Blacksmoke16> to contain the (de)serialization logic specific to that format
<FromGitter> <j8r> hum ok, looks good!
HumanG33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> main thing im sharing is the logic that handles what properties should be skipped via the exclusion strategies and such
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> also like the callbacks
Human_G33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 272 seconds]
Human_G33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 260 seconds]
HumanG33k has joined #crystal-lang
<FromGitter> <j8r> abstract class def are not a thing :(
woodruffw has quit [Ping timeout: 260 seconds]
woodruffw has joined #crystal-lang
<FromGitter> <naqvis> I just can't get my head around the use-case for static abstract methods. Static methods are class level thing and can't be overridden then why there is a need for this?
<FromGitter> <naqvis> also majority (if not all) of well-known languages prohibits this behavior, so that make me believe this isn't something common or there ain't any value in doing so
<FromGitter> <naqvis> just opening a Pandora-box of discussion/comments lol
<FromGitter> <Blacksmoke16> require child classes implement that `self.subscribed_events : AED::SubscribedEvents` method
<FromGitter> <naqvis> i mean you could have circumvent this and would have just asked subscribers to register some callback handler
<FromGitter> <naqvis> isnt' that same thing?
<FromGitter> <naqvis> accept a `Proc` and then just invoking Proc with subscribed events
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Blacksmoke16> the reasoning is *knowing* which events a listener is subscribed to
<FromGitter> <naqvis> yeah, but isn't it the kind of thing which mostly event-streams or message queues does?
<FromGitter> <j8r> @naqvis Otherwise, how to define types for casting? I would like to transform data to `T`
<FromGitter> <naqvis> one can subscribe to any queue or topic or anything
<FromGitter> <naqvis> @j8r are you after something like abstract factory pattern?
<FromGitter> <Blacksmoke16> its also used to control the order in which the listeners are invoked
<FromGitter> <naqvis> or just factory pattern?
<FromGitter> <naqvis> sure, you can store subscribers in array and i believe array maintains the order of insertion
<FromGitter> <j8r> But how doing it with no instances?
<FromGitter> <j8r> Real world simple example https://grip-framework.github.io/gripen/Gripen/Parameters/Path.html
<FromGitter> <j8r> I would like to create a given type from a string
<FromGitter> <naqvis> how and from where you will be invoking `from_string` method?
<FromGitter> <j8r> The route resolver yields each path component as a raw string, with it associated type `T`
<FromGitter> <j8r> Then, `T.from_string(str : String)` creates an instance
<FromGitter> <j8r> Not mentioning that this types are shown in API docs, which is helpful (Not yet with the schemas)
<FromGitter> <naqvis> you are just treating this method as a constructor
<FromGitter> <naqvis> why not invoke the new?
<FromGitter> <j8r> It is the same story: we need a class method accepting one string argument
<FromGitter> <Blacksmoke16> to be fair you could just do
<FromGitter> <Blacksmoke16> ```def self.new(str : String) ⏎ ... ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5ec55a9a63c8e90e43feb013]
<FromGitter> <j8r> Yeah I know, but not really
<FromGitter> <Blacksmoke16> no?
<FromGitter> <j8r> The user won't be able to define its own, and this name is too generic
<FromGitter> <j8r> Both options are similar at the end
<FromGitter> <j8r> I'd like to minimize the risks of collisions with user methods
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <j8r> Anyway, `.new` or `.whatever` - same story :)
<FromGitter> <naqvis> its just you want to enforce sub-class to have specific type constructor with specific set of arguments
<FromGitter> <j8r> absolutely
<FromGitter> <j8r> BTW: there is the same issue on the stdlib
<FromGitter> <j8r> > specify an alternate type for parsing and generation. The converter must define from_json(JSON::PullParser) and to_json(value, JSON::Builder) as class methods
<FromGitter> <j8r> (for converters)
<FromGitter> <naqvis> yeah, but its a run-time thing
<FromGitter> <naqvis> means only at run-time it will raise error, or won't it?
<FromGitter> <naqvis> if you provide converter doesn't fulfill those contracts?
<FromGitter> <Blacksmoke16> pretty sure it wouldnt compile
<FromGitter> <Blacksmoke16> "no overload found"
<FromGitter> <j8r> yep it would not compile
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec55d11cf55346b5fbcc62b]
<FromGitter> <naqvis> that's because of macro
<FromGitter> <naqvis> so it become compile time thing
renich has joined #crystal-lang
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec55e84a1aa566f083a5c88]
<FromGitter> <naqvis> enforcing constructor with specific type
<FromGitter> <naqvis> and if class don't follow the contract, compiler will yell `abstract `def Foo#initialize(val : String)` must be implemented by XYZ`
<FromGitter> <j8r> It works only for initialize, not class methods :/
<FromGitter> <naqvis> yeah I know, but you are using class methods as constructors :)
<FromGitter> <naqvis> that was my point
zorp_ has joined #crystal-lang
<FromGitter> <j8r> don't know, take for example `.from_json`
<FromGitter> <Blacksmoke16> to be fair `from_json` isnt a constructor
<FromGitter> <Blacksmoke16> its just a warpper that ends up calling a `.new` method
<FromGitter> <j8r> yes
<FromGitter> <Blacksmoke16> wrapper*
<FromGitter> <j8r> And it won't be possible to call it `new`
<FromGitter> <naqvis> yeah, but it returns the instance
<FromGitter> <Blacksmoke16> you can have multiple overloads of `new`
<FromGitter> <naqvis> true
<FromGitter> <j8r> Less `initialize` is generally better.
<FromGitter> <Blacksmoke16> is what it does
<FromGitter> <naqvis> but if classes following the contract defined by framework (like they will be sub-classing)
<FromGitter> <Blacksmoke16> with the initialize method a few lines down
<FromGitter> <j8r> @naqvis In my case, from_string is a wrapper, that will call the constructor, which can have additional logic inside
<FromGitter> <j8r> I think having a constructor accepting a string is too much generic, it is safer to have a dedicated class method explaining where it is use for what purpose
<FromGitter> <naqvis> you can enforce some default constructor and then you can have some abstract method like `from_string` defined and have sub-class perform their logic there
<FromGitter> <naqvis> so `Child.new.from_string....`
<FromGitter> <Blacksmoke16> wouldnt work if you need to set ivars based on the string
<FromGitter> <j8r> yeah, ivars would be nillable
<FromGitter> <naqvis> hmmmmm
<FromGitter> <j8r> There is also the unsafe way with `T.allocate` - but meh
<FromGitter> <naqvis> i think we are talking about inheritance here
<FromGitter> <naqvis> child following the contracts set by parent
<FromGitter> <naqvis> its just how to invoke methods
<FromGitter> <naqvis> i mean `from_string(String)` is just a contract which parent is expecting inheriting childs to follow
<FromGitter> <j8r> Note, static methods can be inherited too (I didn't know)
<FromGitter> <naqvis> i don't think so
<FromGitter> <naqvis> Java/C# doesn't allow overriding static methods
<FromGitter> <j8r> https://carc.in/#/r/93z4
<FromGitter> <j8r> and this can be overriden
<FromGitter> <naqvis> ah, inheritance :)
<FromGitter> <Blacksmoke16> also kinda strange imo private methods are inherited too
<FromGitter> <Blacksmoke16> kinda makes `protected` not as useful
<FromGitter> <naqvis> duh?
<FromGitter> <naqvis> if private methods are inherited, how to invoke them?
<FromGitter> <naqvis> just call their name?
<FromGitter> <Blacksmoke16> well what im used to in PHP is private methods are not inherited, they are scoped to that specific class
<FromGitter> <Blacksmoke16> if you want a child to be able to use something defined by the parent you need to make it protected or public
<FromGitter> <Blacksmoke16> protected if you dont want to expose it as a public API ofc
<straight-shoota> visibility operators just have different semantics in different languages
<FromGitter> <naqvis> ```code paste, see link``` ⏎ ⏎ @Blacksmoke16 you are right [https://gitter.im/crystal-lang/crystal?at=5ec563fcb761400e29d93ccc]
<straight-shoota> I honestly don't see any use for private methods being not inherited. A subclass should inherit all the behaviour of the parent and that includes the helper methods that privates often are.
<FromGitter> <Blacksmoke16> yea, I think its a bit strange but :shrug:
<FromGitter> <naqvis> then why the formality of having these access specifiers?
<FromGitter> <Blacksmoke16> there are other semantics around the visibility
<straight-shoota> private methods can't be called from outside the type
<FromGitter> <Blacksmoke16> mainly protected can be used in the same namespace'
<straight-shoota> or outside the instance
<FromGitter> <Blacksmoke16> ^ yea
<straight-shoota> I don't think protected is much useful, though
<FromGitter> <Blacksmoke16> related https://github.com/crystal-lang/crystal/pull/7799
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec56496e4e9556b5c8fc0f4]
<FromGitter> <naqvis> This is Java
<FromGitter> <Blacksmoke16> i usually like to use protected to try and make it more clear that the method is intended to be overridden/extended, not just an implementation detail of the class
<FromGitter> <Blacksmoke16> i.e. you can redefine this method to customize behavior without messing up anything, assuming you follow the return/argument types of it
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec5653e0fbf8b17588324d5]
<straight-shoota> Yeah I guess that's a typical use case that doesn't fit with the visibility modifiers.
<FromGitter> <naqvis> from Crystal reference docs
<FromGitter> <Blacksmoke16> yea, hence that PR, as reading the docs I would like to know what i can do to customize things w/o looking at the source code
<FromGitter> <Blacksmoke16> but :shrug:
<FromGitter> <naqvis> seems i must have skipped through visibility pages `Note that private methods are visible by subclasses:`
<FromGitter> <naqvis> docs does state that
<straight-shoota> Blacksmoke16, yeah but that would just be a hack. Because the original semantics of `protected` don't fit with that use case.
<straight-shoota> Maybe that's fine, but IMO a better solution could be to either redefine protected or introduce a new scope for that
<FromGitter> <Blacksmoke16> it might not be the exact use case as defined in the docs, but given the only options are public, protected, and private. I'm just using protected since its not as common as the other two
<FromGitter> <Blacksmoke16> plus its the only option if you dont want to expose it publicly
<straight-shoota> i.e. methods that are part of the documented interface but are not exposed
<FromGitter> <Blacksmoke16> yea, bcardiff suggested separate sections for it, like `Public` and `Protected`
<FromGitter> <Blacksmoke16> i agree its not super common so dont really matter much
<FromGitter> <Blacksmoke16> i only have like 4 of these protected methods in all my shards, so meh
<straight-shoota> It might actually be more common than you think
<FromGitter> <Blacksmoke16> i mean i think its a common practice, but not with current visibility semantics
<straight-shoota> yeah it really depends on visibility
<straight-shoota> I suppose such methods might often be useful to call externally (and if only for unit tests)
<FromGitter> <Blacksmoke16> works well with php because thats the only way to do it
<straight-shoota> But then you might still not want them documented as external API. So we'd need a separate section for internal API =)
go|dfish has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> id be fine with that
<FromGitter> <naqvis> ```code paste, see link``` ⏎ ⏎ Above definition won't allow shard user to override these protected methods, as 2nd item doesn't meet the criteria, though 1st will be met if user sub-class [https://gitter.im/crystal-lang/crystal?at=5ec5676c63c8e90e43fed362]
<FromGitter> <naqvis> is my understanding correct?
<FromGitter> <Blacksmoke16> i see it often in PHP unit tests since they're just classes. So you could define an abstract test case class, that defines the specs, and then just define some protected abstract methods that the children implement
go|dfish has joined #crystal-lang
<straight-shoota> naqvis, I think so, yes
<FromGitter> <naqvis> if that holds true, then its right decision to not show documentation of protected methods
<straight-shoota> For test code I don't see any benefit in visivility modifiers
<FromGitter> <naqvis> because end-user won't be able to invoke/override them anyway
<FromGitter> <Blacksmoke16> https://carc.in/#/r/93z8
<FromGitter> <Blacksmoke16> is what i meant
<straight-shoota> naqvis, but they can in inheriting types
<FromGitter> <Blacksmoke16> > *<straight-shoota>* For test code I don't see any benefit in visivility modifiers ⏎ ⏎ not right now yea, see https://github.com/crystal-lang/crystal/issues/8289#issuecomment-604523903
<straight-shoota> even in a class based test system I don't see the purpose of visbility modifiers
<straight-shoota> test code is not a public API
<FromGitter> <Blacksmoke16> i think in PHP land public methods are ran as test cases
<FromGitter> <Blacksmoke16> er that begin with `test_`
<FromGitter> <Blacksmoke16> but yea, doesnt matter too much in that case
<FromGitter> <naqvis> straight-shoota ah so that is an `OR` condition, i was thinking that is `AND`
<FromGitter> <naqvis> ```code paste, see link``` ⏎ ⏎ I thought it was already closed, but issue still open https://github.com/crystal-lang/crystal/issues/8328 [https://gitter.im/crystal-lang/crystal?at=5ec56d7ce06728175b7ed00b]
<FromGitter> <kinxer> Can you only use tuple literals in assignment? https://carc.in/#/r/93zu
<FromGitter> <Blacksmoke16> need `()`
<FromGitter> <Blacksmoke16> since there isnt a way to tell that apart from a block
<FromGitter> <kinxer> Ah... Thank you.
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9409
<raz> a thing that bugs me about enums is how you have to get very verbose to reference them in method calls :(
<FromGitter> <Blacksmoke16> *lies*
<raz> wait..wot
<FromGitter> <Blacksmoke16> symbols get auto casted to enum members
<FromGitter> <Blacksmoke16> in most cases
<raz> duh!
<raz> whenever i find something to complain about you just ruin my perfect little rant before i can even start it
* raz sighs and goes back to do some bulk code replacements
<FromGitter> <Blacksmoke16> 😎
<FromGitter> <kinxer> I mean, on the other hand... Aren't symbols still potentially on the chopping block in the future?
<FromGitter> <Blacksmoke16> yes, but the idea is to just make them solely for auto casting enums
<FromGitter> <kinxer> I saw that you'd proposed that; is that being widely accepted? I've not followed those conversations.
<FromGitter> <kinxer> Okay, so the plan all along for getting rid of symbols was to keep the `:name` syntax as an enum shorthand?
<FromGitter> <Blacksmoke16> afaik yea
_ht has quit [Quit: _ht]
<raz> when symbols are treated as strings we could still keep the symbol syntax as a shorthand in general, too.
<raz> not sure how useful it would be in practice, but i suppose then you could also do foo("enum_value") instead of foo(:enum_value)
<FromGitter> <Blacksmoke16> pretty sure `:enumvalue` would work too
<raz> hmm yea, on second thought. perhaps not a good idea. better to leave the symbol-syntax only for special cases like enum values
<raz> (less ambiguity)
<FromGitter> <Blacksmoke16> mhm, atm symbols can also be defined as like `:"I have spaces"`
<raz> yap, that's usually when you notice "wait, something's wrong here" :P
_whitelogger has joined #crystal-lang
<oprypin> raz, what are you talking about, symbols treated as strings
<oprypin> nobody wants that, ever
<raz> oprypin: yes, everyone wants that. them being different was just a misunderstanding by ruby ¯\_(ツ)_/¯
<oprypin> raz, look, ruby is sill and that's ok. but in crystal symbols actually have a point - their great efficiency
<oprypin> silly*
<raz> i thought it's the other way round (ruby made symbols special cause it's slow - crystal doesn't have that excuse :))
<raz> buuut i'm willing to be convinced otherwise if it would really make crystal lots slower (and i know it's not gonna happen anytime soon anyway, if ever). my thinking is the compiler could still be smart about interning strings in many places. 🤔
<FromGitter> <kinxer> I've been thinking about the performance issue in that forum thread (significant performance degradation between 0.30.0 and 0.31.0); would use of fibers without the opt-in multithreading compilation flag cause performance degradation? I know there's overhead for managing multithreaded fibers, but is that applicable without the compilation flag?
<oprypin> probably not i dunno
<oprypin> look i dont know what the mess is all about, you literally just go ahead and git-bisect it
<oprypin> but of course their code is private so im like... whatever have fun
<FromGitter> <kinxer> That's fair. I'm just putting effort into it to match my interest; if it stops being interesting to me, I'll stop going out of my way to solve a problem with not enough information.
<FromGitter> <kinxer> And it's really just an interstitial thing for me right now (a break from a weird geometry thing I have to implement in Java that's giving me trouble).
<raz> hm yea, that thread sounds like exactly what git bisect was made for
<raz> he could probably pinpoint it down to the offending commit
<raz> i wonder if anyone else has noticed a perf regression (like the ppl in here who keep tuning their web frameworks)
<raz> personally i haven't, but i also haven't paid specific attention
<FromGitter> <Blacksmoke16> same
<raz> blacksmoke: does athena have a benchmark suite?
<raz> might be interesting to try it out with 0.30 vs .34
<raz> if it still compiles on .30 that is ;)
<FromGitter> <Blacksmoke16> it wouldnt
<FromGitter> <Blacksmoke16> `0.35.0` will be min version here soon
<raz> yea then not worth it