<FromGitter>
<Blacksmoke16> prob a good habit for you to get used to 😉
absolutejam2 has joined #crystal-lang
<FromGitter>
<tenebrousedge> or not
<FromGitter>
<tenebrousedge> if crystal core switches gears and implements explicit return typing, then I will adopt the fashion
<FromGitter>
<Blacksmoke16> i mean its a feature of the language that you dont have to
<FromGitter>
<Blacksmoke16> but :shrug:
<FromGitter>
<tenebrousedge> and I may decide later that it suits me
<FromGitter>
<tenebrousedge> but at the moment, I'm aware of the arguments for and against, I'm pretty conversant in the language and its idioms, and I don't currently see a need for it. Ask me again in two years
<hightower2>
Folks why would "# ditto" not copy the previous description onto the current item? The behavior I see is that the original item has docs, but the one which is "# ditto" just prints "ditto"
<FromGitter>
<Blacksmoke16> :ditto:
<FromGitter>
<Blacksmoke16> The colons are required
<hightower2>
Tried with them too (even though this is not mentioned on crystal
<hightower2>
crystal's documenting_code.html page
<hightower2>
in some places it works (# ditto) in others not at all and just prints ditto. Will check what/where influences that later, don't have time right now as I'm trying to wrap up for the day
<hightower2>
Is it possible that it doesn't work on constants
<FromGitter>
<Blacksmoke16> Possibly
<FromGitter>
<Blacksmoke16> It's more so for methods
<hightower2>
yeah confirmed, ditto doesn't work on constants, gonna file a bug report
<FromGitter>
<vlazar> MT Python and the holy grail
fyber has quit [Ping timeout: 240 seconds]
fyber has joined #crystal-lang
DTZUZO has joined #crystal-lang
duane has joined #crystal-lang
DTZUZO has quit [Ping timeout: 268 seconds]
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 264 seconds]
<FromGitter>
<straight-shoota> Now we only need an equally efficient MT Bugfixer =)
Plazma has joined #crystal-lang
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 250 seconds]
DTZUZO has joined #crystal-lang
<FromGitter>
<bararchy> oh no
<FromGitter>
<bararchy> maybe @waj ;)
<FromGitter>
<bararchy> or @asterite heheh
<FromGitter>
<bararchy> TBH I think most of the fixes are either @waj or @bcardiff
DTZUZO has quit [Ping timeout: 276 seconds]
<FromGitter>
<Blacksmoke16> `make docs`
<FromGitter>
<Blacksmoke16> assuming you for mean for crystal itself
<FromGitter>
<Daniel-Worrall> ya, I was trying crystal docs and obvs it's complaining about already defined constants
<FromGitter>
<naqvis> @Blacksmoke16 believe `make docs` is valid, if one is building from sources. Would it apply to version installed via package managers like brew, apt etc?
<FromGitter>
<naqvis> is there any way for one to generate API docs locally from installed version?
<FromGitter>
<Blacksmoke16> not that i know of
<FromGitter>
<naqvis> thank you @Blacksmoke16
<FromGitter>
<Daniel-Worrall> There isn't. You need the source to get docs. I'd appreciate if it was downloadable and also if there was a local mode that didn't generate the icons on readme since they connect to the network
<FromGitter>
<Daniel-Worrall> I can just remove them manually but I'd have to do that after each build
<FromGitter>
<straight-shoota> > There isn't. You need the source to get docs. ⏎ ⏎ Yes there is. The stdlib sources are usually distributed with every Crystal packages. Otherwise you'd have no stdlib.
<FromGitter>
<straight-shoota> @naqvis The `Makefile` is not distributed, but the `docs` task is pretty simple to reproduce manually: `crystal docs /usr/share/crystal/src/docs_main.cr`. ⏎ `/usr/share/crystal/src` is the location of the stdlib and may vary depending on your platform and installation method. It should be shown by `crystal env CRYSTAL_PATH`.
<FromGitter>
<kinxer> I don't think it's distributed with Crystal.
<FromGitter>
<Daniel-Worrall> It isn't, I was asking if there is an easier way to acquire than building myself
<FromGitter>
<Blacksmoke16> i mean just download it, its just a bunch of markdown files
ht_ has joined #crystal-lang
ht_ has quit [Remote host closed the connection]
ht_ has joined #crystal-lang
DTZUZO has quit [Ping timeout: 268 seconds]
Human_G33k has quit [Ping timeout: 268 seconds]
<FromGitter>
<repromancer_gitlab> @Daniel-Worrall I was just checking out the https://devdocs.io link, and it has the Crystal GitBook, though not presented the same way
HumanG33k has joined #crystal-lang
dwdv_ has joined #crystal-lang
absolutejam2 has joined #crystal-lang
absolutejam2 has quit [Ping timeout: 268 seconds]
<FromGitter>
<ImAHopelessDev_gitlab> Dyscalculia kicking in.. can anyone help me
<FromGitter>
<tenebrousedge> 2 + 2 = 5
<FromGitter>
<tenebrousedge> (for large values of 2)
<FromGitter>
<tenebrousedge> because floating point math?
<FromGitter>
<ImAHopelessDev_gitlab> is it possible to increase a value by a percentage and decrease it by the same percentage? up 5%, down 5% and retain the same number?
<FromGitter>
<ImAHopelessDev_gitlab> in my example, 5%
<FromGitter>
<tenebrousedge> waitasec
duane has quit [Ping timeout: 265 seconds]
<FromGitter>
<kinxer> When you do the `-=`, `test1` is equal to `105.0`, and `105.0 * 5 / 100` is not `5`.
<FromGitter>
<tenebrousedge> ^
<FromGitter>
<ImAHopelessDev_gitlab> WTF
<FromGitter>
<tenebrousedge> store the base value as well as the modified value
<FromGitter>
<ImAHopelessDev_gitlab> so for simple addition/subtraction, a `base` value isn't really needed. but for increasing by a percentage, `base` is a must?
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
<FromGitter>
<tenebrousedge> if you want it to be the same percentage each time
dannyAAM has joined #crystal-lang
<FromGitter>
<ImAHopelessDev_gitlab> interesting, i thought increase/decreasing by a percentage would result in the same value. like addition/subtraction. TIL
<FromGitter>
<ImAHopelessDev_gitlab> WOW that's so weird why i thought that, WTF
duane has joined #crystal-lang
<FromGitter>
<ImAHopelessDev_gitlab> Thanks! I got it now
<hightower2>
is there a way to represent infinity?
<FromGitter>
<Blacksmoke16> `Float64::INFINITY`
<FromGitter>
<tenebrousedge> why?
<hightower2>
I have a number which as the algorithm runs is getting closer and closer to 0, but it needs to start from some highest/impossible value
<hightower2>
I could probably get away with just using UInt64::MAX or something
<hightower2>
but still, asked just to know
<FromGitter>
<tenebrousedge> kk
dwdv_ has quit [Ping timeout: 268 seconds]
absolutejam2 has joined #crystal-lang
Nekka has quit [Read error: Connection reset by peer]
Nekka has joined #crystal-lang
absolutejam2 has quit [Ping timeout: 264 seconds]
rohitpaulk has joined #crystal-lang
absolutejam2 has joined #crystal-lang
<FromGitter>
<ImAHopelessDev_gitlab> WOW, `base` values dealing with percentages are like the foundation of character stats
<FromGitter>
<ImAHopelessDev_gitlab> this is awesomeeeeeeeeeeee
<FromGitter>
<tenebrousedge> 👍
<FromGitter>
<christopherzimmerman> Is there an equivalent of `Array.product` that can yield from ranges rather than arrays? I am trying to generate indexes for arbitrarily shaped containers, and for large containers its memory intensive to have to pre-compute all the inner ranges. Here's what I have now: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ I want to make this as memory friendly as possible, I never need to store the
<FromGitter>
<asterite> I think you'll need to code it youself: start with a zero array, then increment, yield, increment, yield, etc.
<FromGitter>
<tenebrousedge> sounds like a job for `Iterator`
<FromGitter>
<tenebrousedge> I'm not sure I get what that code does
<FromGitter>
<tenebrousedge> there is an `each_product`, if you need it
<FromGitter>
<ilanpillemer> Iteraror Fan!
<FromGitter>
<tenebrousedge> it's a thing. increment + yield is pretty much what `next` does
<FromGitter>
<tenebrousedge> or can do
<FromGitter>
<christopherzimmerman> The code just generates array indices. So if I have a (2, 2) shaped array, the indices will look like: ⏎ ⏎ ```# [0, 0], [0, 1], [1, 0], [1, 1]``` ⏎ ⏎ I just need that generalized to `n` dimensions. [https://gitter.im/crystal-lang/crystal?at=5db8a5de14d55a37859b765c]
<FromGitter>
<christopherzimmerman> Julia has `Iterators.product` (https://docs.julialang.org/en/v1/base/iterators/#Base.Iterators.product), I thought there might be something similar. But it won't be hard to implement that as an `Iterator`
<FromGitter>
<christopherzimmerman> Although for the time being, `each_product` definitely is closer to what I want, since it avoids the massive `product` array. being created: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5db8a7adfb4dab784a2abc15]
<hightower2>
Hey so I have classes X and X::Y. I have class X in a variable. How do I get from there to the variable containing X::Y ?
<FromGitter>
<Blacksmoke16> idt you can
<FromGitter>
<tenebrousedge> sounds like a metaprogramming thing
<FromGitter>
<Blacksmoke16> like idt think `my_var::Y` would work
<hightower2>
Blacksmoke16 hm if there's no direct way to do it, then since this is part of that our Events thing, I can just add a class method which returns {{e.id}}::Y
<Stephanie>
it's amazing how all the existing ones are weird macro DSLs of some kind
<Stephanie>
and this is like, 200loc, and 100 of those are comments...
<FromGitter>
<tenebrousedge> o.o DSLs are a thing
<FromGitter>
<tenebrousedge> I'm not sure that e.g. `rake` and derivatives were well thought out
<Stephanie>
this is a DSL too!
<Stephanie>
just, doesn't have to be overdone with macros to be beautiful
<FromGitter>
<bajro17> Hello guys
<FromGitter>
<tenebrousedge> yo
<hightower2>
Blacksmoke16 hm I got blocked on something, so when we run inside {% for e in Event.subclasses %}, is it possible to retrieve the full list of class' args, like x : Int32, y : Int32 ? I see there is 'args', but it only contains array of types, not the complete thing with var names
<FromGitter>
<bajro17> How to write this like regex "GET|/user/([^/]+)/"
<hightower2>
hi bajro17
<FromGitter>
<bajro17> what I need to escape I cant figure out
<hightower2>
bajro17 seems like you want all the chars until the first next /. You can do this with .*?/ or .+?/ , the ? will switch to non-greedy match and will stop as early as possible, which is on the first /
<hightower2>
so you want /(.+?)/
<FromGitter>
<tenebrousedge> I might leave off the `?`
<FromGitter>
<bajro17> I want when compare GET|/user/([^/]+)/ with GET|/user/name to get only name
<hightower2>
yes this seems like it will do it
<FromGitter>
<tenebrousedge> `/user\/(.+)/`
<FromGitter>
<tenebrousedge> or `/\w+/\K.+/`
<FromGitter>
<tenebrousedge> I'm not sure if the `/` needs to be escaped
<hightower2>
Blacksmoke16 (found it, all good)
<FromGitter>
<bajro17> how can I use %r in this case
ht_ has quit [Remote host closed the connection]
<FromGitter>
<Blacksmoke16> 👍
<FromGitter>
<tenebrousedge> `%r(\/\w+\/\K.+)`, depending on if you need to deal with trailing slashes
<hightower2>
Blacksmoke16 hm another one, so I am trying to write a macro named 'event' which runs these two lines for me: record MyEvent < Event. ...args... , and another very similar line record MyEvent::Element > Event ... same args... So it would be just a handy way to create both at once. Any suggestions how to do it? My attempts didn't work, I think I lost some arguments in the process
<hightower2>
how can I get a full name of class like X::Y::Z rather than just Z?
<hightower2>
{{ e.? }}
<hightower2>
or, maybe the issue is something else.. nvm
<hightower2>
yeah I'd appreciate a doublecheck on macro syntax. If the syntax is "record X < Event, args...", how do I write a macro that takes the same arguments and just calls that line?
<hightower2>
(I am asking because when we determine what the macro for this is, I'll add another call in it, that's not part of the current question)
<hightower2>
I tried with macro(name, *properties), is that oK?
<hightower2>
I tried with macro mymacro(name, *properties); record {{name}}, {{*properties}} end , is that OK?
<FromGitter>
<Blacksmoke16> prob want to do `macro(name, **properties)`
<FromGitter>
<Blacksmoke16> then do like `record {{name}}, {{properties.double_splat}}`
<hightower2>
hmm, tried it, called the macro "event", and then I get an error on line "event MyEvent < Event, message : String" -> Undefined constant MyEvent
<hightower2>
not sure why it tried to resolve it, this is the line where I am defining it
<FromGitter>
<Blacksmoke16> shouldnt that be `record` not `event`
<hightower2>
yes but this is the location of my calling the macro called "event". This macro would then call "record" with identical args
<FromGitter>
<Blacksmoke16> tbh why not just define them separately
<hightower2>
Blacksmoke16 yrah but it'd be lame that every event would have to be defined with two lines, one defining MyEvent, and second defining ElementMyEvent, both with identical arguments and everything
<FromGitter>
<Blacksmoke16> oh i misunderstood what you were doing
<FromGitter>
<Blacksmoke16> what is `ElementMyEvent`?
<hightower2>
If no handlers are found for MyEvent, then the event system automatically tried emitting another event called ElementMyEvent (fixed prefix "Element", followed by the original event name)
<hightower2>
s/tried/tries/
<FromGitter>
<Blacksmoke16> ah ok
<FromGitter>
<bajro17> str.match(/(?<=GET:\/user\/)(.+)/i).try &.[0] this work even better
<hightower2>
So, I have the first part handled, in the macros I define class method "element" which returns Element<Event>. But I have trouble defining this second event automatically
<FromGitter>
<Blacksmoke16> got a full example?
<hightower2>
yeah I can cobble some pseudo-code, on it
<FromGitter>
<Blacksmoke16> of just the macro
<FromGitter>
<Blacksmoke16> so like parent class and the macro would be enough
<hightower2>
the modification to it would be that somehow when MyEvent is created, the macro automatically creates both MyEvent and ElementMyEvent
<hightower2>
(both with same args)
<FromGitter>
<tenebrousedge> @bajro17 you might want to use `String#[](Regex)`
<hightower2>
Blacksmoke16 I tried doing it with a macro called "event" which would first call "record {{name}}, ...", then "record Element{{name}}, ...", however wasn't successful)
<FromGitter>
<bajro17> how can I get last cahracter in string
<FromGitter>
<Blacksmoke16> `str.last`?
<FromGitter>
<tenebrousedge> naw
<FromGitter>
<tenebrousedge> `str[-1]`
<FromGitter>
<bajro17> I want instead of /user/ to get \/user\/
<FromGitter>
<Blacksmoke16> boo
<FromGitter>
<tenebrousedge> there isn't a `String#last`
<hightower2>
Blacksmoke16 hm hm, no luck. At place of definition, where I write define_event(Xyz, ...) it tells me undefined constant Xyz
<FromGitter>
<Blacksmoke16> quote it
HumanG33k has quit [Remote host closed the connection]
<hightower2>
That did it, now I get wrong number of arguments for define_event -- given 2, expected 1. (I think this is because these macros don't treat "arg : type"s as hash, but as array (e.g. macro 'record' accepts them with *properties, not **properties)
<FromGitter>
<Blacksmoke16> right it has to be `name: String`
<hightower2>
not only it works, but also it doesn't throw undefined error any more, so don't need to quote
<hightower2>
brilliant, thanks
<FromGitter>
<Blacksmoke16> Np
<hightower2>
after finishing the tests, etc. this means I'll have the event model fully done in the next 30 mins or so
<FromGitter>
<Blacksmoke16> Nice one
<hightower2>
Ah final question... in a macro, how can I determine the "full path" of a class?
<FromGitter>
<Blacksmoke16> Hm?
<hightower2>
I have "def {{e.id}}.element; Element{{e.id}}; end ... however, in places where this is called, if someone calls MyEvent.element, it returns ElementMyEvent, which ends up being undefined
<hightower2>
whereas if it returned ::Path::To::ElementMyEvent, it'd work
<hightower2>
yep, seems that would do it, now to figure out how to combine a string ("Element") with type to get new type on which I can call .resolve
<hightower2>
hm, or not sure if it expanded it or not.. seems like x.resolve == x
<blassin>
how do I split a string like "00000000" into an array with 4 sets of "00" ? I tried string.split(/\.{2}/) but it gives me ["","","",""]
<FromGitter>
<tenebrousedge> `string.each_char.each_slice(2)` or `string.scan(/../).map &.[0]`
<blassin>
thanks!
<FromGitter>
<tenebrousedge> np
<hightower2>
Blacksmoke16 I have an idea. The name of this "element" class which I'd prefer would be MyEvent::Element. So I made the changes so that this gets created. Now, when context is inside MyEvent, then just "Element" would resolve to that subclass, right? Also I seem to recall there is that 'with' keyword. So it is possible to do something like def {{e.id}}.element: with {{e.id}} return Element end ?
<FromGitter>
<Blacksmoke16> Uhh
<FromGitter>
<Blacksmoke16> Got a playground link?
<hightower2>
no, still trying it out, "with" seems to only want "yield" afterwards which is about blocks, which I don't see how they'd help here
<hightower2>
still playing around with it
<FromGitter>
<Blacksmoke16> Ok
<hightower2>
isn't there some const_get or something defined on classes? So that I could do {{e.id}}.const_get("Element") ?
<FromGitter>
<Blacksmoke16> Couldn't you just do
<FromGitter>
<Blacksmoke16> `{{e.id}}::Element`
<hightower2>
I did. Tells me it's undefined.
<FromGitter>
<Blacksmoke16> Rgr
<hightower2>
Called macro defined in src/event_emitter.cr: {% begin %} which expanded to def ClickedEvent.element; ClickedEvent::Element, error: undefined constant ClickedEvent::Element
<FromGitter>
<Blacksmoke16> Yea without a code example I dunno
<hightower2>
gonna try make one, sec
<FromGitter>
<Blacksmoke16> Kk
<hightower2>
Hm, https://play.crystal-lang.org/#/r/7wyk works. is it possible that when we call Event.subclasses, we get ClickedEvent before ClickedEvent::Element, even though I defined the ::Element one first?
<FromGitter>
<Blacksmoke16> Possibly
<hightower2>
maybe we could do .subclasses.sort by length, from longest first
<hightower2>
yes, indeed, it comes before ::Element
<hightower2>
regardless in which order I define them. So maybe just reverse the list, if .reverse exists
<FromGitter>
<Blacksmoke16> I guess
<hightower2>
hm, I see there is sort_by on ArrayLiteral, but not sure how to call it?
<FromGitter>
<Blacksmoke16> Just like you would on a normal array
<hightower2>
If I do {% for e in Event.subclasses.sort_by { |w| -w.size } %}, it tells me
<hightower2>
ah got it, -w.name.stringify.size
<hightower2>
however,
<hightower2>
aaah, kill me, wait a second
<hightower2>
this was a custom event for which I forgot to start using define_event(), so it didn't create the ::Element one. I also confirmed that with define_event(), no sort is necessary