ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.32.1 | 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> <manveru> Is there a way to force HTTP::Client to use IPv6? looking for the equivalent of `curl -s6`...
alex` has joined #crystal-lang
alex` is now known as Guest60335
alexherbo2 has joined #crystal-lang
<FromGitter> <tenebrousedge> you can give it the IPv6 address instead of a hostname, perhaps
<FromGitter> <tenebrousedge> possibly resolving it first
Guest60335 is now known as alex``
<FromGitter> <manveru> ok, thanks
mistergibson has quit [Quit: Leaving]
alex`` has quit [Ping timeout: 268 seconds]
alexherbo2 has quit [Ping timeout: 265 seconds]
<FromGitter> <Blacksmoke16> any good ways to access `T` in `Array(T)` outside of the type itself?
<FromGitter> <Blacksmoke16> i.e.
<FromGitter> <Blacksmoke16> ```type = Array(String) ⏎ ⏎ type.? # => String``` [https://gitter.im/crystal-lang/crystal?at=5e36297b40da694c5e01749d]
<FromGitter> <Blacksmoke16> oh
<FromGitter> <Blacksmoke16> this is what `forall` is for
<FromGitter> <Blacksmoke16> 👍 nvm
<FromGitter> <mistergibson> I'd like to develop with crystal on the ppc (PowerPC) 64bit platform. Where do I check up, from time to time, on the multi-arch porting efforts?
<FromGitter> <mistergibson> Essentially, I'd like to run crystal programs anywhere I can run Ruby apps.
<FromGitter> <mistergibson> sweet : thanks
<FromGitter> <Blacksmoke16> or better yet a PR to add it 😉
<FromGitter> <Blacksmoke16> afaik you just have to fill in the `lib_c` stuff? See https://github.com/crystal-lang/crystal/pull/5861
<FromGitter> <Blacksmoke16> prob easier said than done ha
<FromGitter> <rurounijones_gitlab> Say I have a hash where the values are `String | BigDecimal | Float64` then I do some fiddling and the values are now only `String | Float64`. Is there a way to have the Hash's types recalculated to reflect the updated values? I am assuming I could create a new hash and copy the values across but I was wondering if there way another way
<FromGitter> <Blacksmoke16> naw, would have to make a new hash
<FromGitter> <Blacksmoke16> as the types are tied to the instance of `Hash`
<FromGitter> <Blacksmoke16> or might be better to use structs, depending on what you're doing
<FromGitter> <rurounijones_gitlab> Bleh, didn't think so, was hoping. Ach well off to create more hashes
<FromGitter> <Blacksmoke16> 😬
<FromGitter> <Blacksmoke16> what are you trying to do?
<FromGitter> <rurounijones_gitlab> Data source is format A - Target requires format B - Munging data from one to the other
<FromGitter> <rurounijones_gitlab> which requires fiddling with A then merging A with another copy of A that is updated compared to the original
<FromGitter> <Blacksmoke16> i see
<FromGitter> <Blacksmoke16> is a hash the best structure to use?
<FromGitter> <rurounijones_gitlab> Structs don't have .each
<FromGitter> <rurounijones_gitlab> And need mutable so NamedTuples and Tuples are out
<FromGitter> <Blacksmoke16> you can define it yourself and include `Enumerable`
<FromGitter> <Blacksmoke16> got a simple playground example?
<FromGitter> <rurounijones_gitlab> No, nothing playground'ish. I also need the ability to reference things using a[key] and since Crystal doesn't have #send
<FromGitter> <Blacksmoke16> possible a diff approach that doesn't require that would be better?
<FromGitter> <Blacksmoke16> even using a struct that would result in a union of all types
<FromGitter> <rurounijones_gitlab> I could possible use structs everywhere and then explicitly reference every attribute that needs updating instead of using `.each` to iterate but since "redefine the hash" is hopefully the last blocker to getting this working I am goign to do that then think about alternatives
<FromGitter> <Blacksmoke16> okey dokey
<FromGitter> <Blacksmoke16> id have to see an example to have anymore ideas
<FromGitter> <rurounijones_gitlab> This is a port of Ruby code ( https://gitlab.com/overlord-bot/tac-scribe ) - When I get it working in crystal I will put it up in ( https://gitlab.com/overlord-bot/tac-scribe-crystal ) (There is some code in there already but not the painful bits)
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <rurounijones_gitlab> Can anyone sanity check this. AFAIK this should work looking at docs and examples. The fact that the prepared statement in the error message is "" is suspicious ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ `Unhandled exception in spawn: bind message supplies 1 parameters, but prepared statement "" requires 0 (PQ::PQError)` [https://gitter.im/crystal-lang/crystal?at=5e36487ad9895b17c3c74236]
Dreamer3 has quit [Ping timeout: 268 seconds]
Dreamer3 has joined #crystal-lang
Dreamer3 has quit [Ping timeout: 268 seconds]
nonuse has joined #crystal-lang
Dreamer3 has joined #crystal-lang
Dreamer3 has quit [Ping timeout: 265 seconds]
Dreamer3 has joined #crystal-lang
nonuse has left #crystal-lang ["WeeChat 1.6"]
<FromGitter> <grkek> @confact Damn nice star from me
<FromGitter> <grkek> quick note the http.cr file is out of the src folder which is not recommended at all you can do it but your source code should be in the src folder always.
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
alex`` has joined #crystal-lang
alexherbo2 has joined #crystal-lang
fifr has quit [Ping timeout: 260 seconds]
fifr has joined #crystal-lang
<alex``> how to convert a time range to an array of time with a given interval?
<alex``> today -> next month, with interval '2 days' being a list of every 2 days to the next month
_whitelogger has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> UNLEASH the Enums!
<FromGitter> <ImAHopelessDev_gitlab> @rurounijones_gitlab try `where id = ?`? not sure
<FromGitter> <ImAHopelessDev_gitlab> mysql does the escaping internally with prepared
lvmbdv has quit [Quit: HE COMES]
lvmbdv has joined #crystal-lang
<alex``> @ImAHopelessDev do you have an example?
Dreamer3 has quit [Ping timeout: 265 seconds]
Dreamer3 has joined #crystal-lang
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 260 seconds]
<alex``> is there a shortcut to `list.map { |item| something(item) }`
<alex``> found `&->something(String)`
<alex``> I figured out myself but I can't find the doc for it
<alex``> is it a lost of time to iterate multiple times, instead of doing all the work in a single loop?
<alex``> ``` crystal
<alex``> tokens = tokenize(text)
<alex``> times = tokens.map &->Parser.parse(String)
<alex``> times.reduce do |compiled_time, time|
<alex``> compiled_time + from_now(time)
<alex``> end
<alex``> ```
<FromGitter> <straight-shoota> alex`` yes it's more performant to put all operations in a single iteration
<FromGitter> <straight-shoota> The biggest saving is probably that `#map` allocates a new array.
<alex``> what do you suggest?
<alex``> absolute, ...relatives = tokenize(text)
<alex``> ?
<FromGitter> <straight-shoota> Not sure what you mean with `absolute, ...relatives = tokenize(text)`
<FromGitter> <straight-shoota> Your snipped could just be written like this: ⏎ ⏎ ```tokenize(text).sum do |time| ⏎ from_now(Parser.parse(time)) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e36c1c358f02e34975b3d2d]
<alex``> "2019-03-12 + tomorrow" -> ["2019-03-12", "tomorrow"]
<FromGitter> <straight-shoota> `sum` is equivalent to your `reduce` call
<alex``> hm
<alex``> I parse parse the first token, but not call from_now on it
<alex``> s/parse/want/
<FromGitter> <straight-shoota> That's what you did in your sample
<alex``> ah?
<alex``> times.reduce without initial value takes the first argument, so from_now(time) is not called on it no?
<alex``> first element*
<FromGitter> <straight-shoota> `#reduce` yields the memo as first argument
<FromGitter> <straight-shoota> The second argument (`time`) is the item of `times` and it's passed to `from_now`.
<alex``> yes but you have done `tokenize(text).sum do |time|`, while it still a `token` (string) at that time
<FromGitter> <straight-shoota> The equivalent implementation using `reduce` would be this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36c3eb58f02e34975b4283]
<alex``> it is the full code
<FromGitter> <636f7374> Oops! I encountered a very strange problem again
<FromGitter> <636f7374> ```Duplicate large block deallocation ⏎ Abort trap: 6``` [https://gitter.im/crystal-lang/crystal?at=5e36d383433e1d40398f5217]
<FromGitter> <636f7374> After running the program for a while, it will have this crash.
<FromGitter> <636f7374> After I added same_thread, the problem of `pointer being freed was not allocated` disappeared, but the problem of` Duplicate large block deallocation` appeared.
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36d45673ddad4acd8a6491]
<FromGitter> <636f7374> Occurs sometimes, infrequently.
<FromGitter> <636f7374> Okay, appeared on macOS user reports.
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36d5bf15941335585003fd]
return0e_ has quit [Ping timeout: 268 seconds]
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36d6e258f02e34975b6aba]
<FromGitter> <636f7374> Looks like the cache is not safe, I need to reimplement it.
<FromGitter> <636f7374> It's really weird, have you encountered similar problems (in Hash)?
return0e has joined #crystal-lang
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36da81bfe65274ead64901]
<FromGitter> <636f7374> similar.
<alex``> how to implement time range for iteration?
<alex``> I have this version which works https://gist.github.com/8d68a2b24dcd0dbcdf63228e46731322
<alex``> not sure of the best way to do
<FromGitter> <636f7374> OKay, I found it, the problem is caused by different threads inserting data.
<FromGitter> <tenebrousedge> the TimeRange looks fine. You might consider whether Iterable would be better than Enumerable; I don't know that it would make much difference.
<alex``> I changed the implementation like this:
<alex``> the interface is more friendly using range
<alex``> TimeRange.new(7.days.ago..tomorrow)
<alex``> TimeRange.step(1.day)
<alex``> btw, what do you recommend as a default 'step'?
<alex``> day, second, nanosecond?
<alex``> in my implem, what I have to change?
<alex``> looks they both use #each
<FromGitter> <tenebrousedge> default step should be second
<FromGitter> <tenebrousedge> `Iterable` uses `next`
<alex``> do you have an exemple link?
<alex``> ah, found it bellow
<alex``> the difference between the 2, iterator and enumerable, is enumerable collect all the data, while iterator is lazy?
<FromGitter> <tenebrousedge> yes
<alex``> iterator is much better for me so
<alex``> thanks for the tips
<FromGitter> <tenebrousedge> you may as well provide both initializers
<FromGitter> <tenebrousedge> one with the range, and the other with separate arguments
<alex``> what do you mean by both initializers?
<alex``> btw I got a type inference error by doing `@time = @range.begin`
<alex``> I had to add `property time : Time`
<FromGitter> <Blacksmoke16> id do ⏎ ⏎ ```def next ⏎ return stop if @time < @range.end ⏎ ⏎ @time += @step ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e36e500f301780b8360292e]
<alex``> while `@range is Range(Time, Time)`, how can I do?
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36e564f301780b83602a21]
<alex``> OH
<alex``> I never think to overloading because ruby
<alex``> Blacksmoke16: it's not `return stop if @time > @range.end` instead?
<FromGitter> <Blacksmoke16> oh prob yea ⏎ good call
<alex``> I found one-liner less readable
<alex``> visually I see more rapidly what code does when it has blocks
<FromGitter> <Blacksmoke16> fair enough
Yxhuvud has joined #crystal-lang
<alex``> tenebrousedge I have the following error now
<alex``> this 'initialize' doesn't explicitly initialize instance variable '@begin' of TimeRange, rendering it nilable
<FromGitter> <Blacksmoke16> try making the first one `def self.new` instead
FromGitter has quit [Remote host closed the connection]
FromGitter has joined #crystal-lang
<alex``> hm
<alex``> it works.. but I don't know why
<FromGitter> <tenebrousedge> initialize is special
<alex``> there is something that bug me, is step = 1.second
<alex``> default value in both
<alex``> I want just to forward
<alex``> removing default value in self.new works now
<alex``> black magic
<alex``> step in the initializer is out of the scope to you?
<alex``> or it is fine to include it when creating the object
<alex``> it looks a bit more natural to me to define it not in the object creation
return0e has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> wouldnt you need to define it in both so no matter what overload is used it works correctly
<FromGitter> <Blacksmoke16> otherwise i guess you could make it nilable, and within the actual initializer check if nil, if so use 1.second otherwise use the given value
<alex``> I'm pretty happy with the code now. thanks you for your help and useful tips
return0e has joined #crystal-lang
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <grkek> This might sound idiotic but I am trying to create an UI framework
<FromGitter> <grkek> based on GTK
<FromGitter> <grkek> https://github.com/grkek/flare
<FromGitter> <grkek> check it out
<FromGitter> <grkek> there are some horrible macro bendings and etc which needs work but yeah
<FromGitter> <636f7374> I prefer native UI.
<FromGitter> <636f7374> like libui
<FromGitter> <grkek> Good for you, I prefer to design my UI in a designer
<FromGitter> <636f7374> okay
<FromGitter> <636f7374> https://github.com/Fusion/libui.cr
<FromGitter> <grkek> Looks nice
<FromGitter> <636f7374> @grkek These repositories have not been maintained for a long time.
<FromGitter> <636f7374> Some may malfunction.
<FromGitter> <grkek> I didn't like libui
<FromGitter> <grkek> at all
<FromGitter> <grkek> because it was too much trouble to set it up correctly
<FromGitter> <grkek> on the other hand the gtk lib doesnt have a pre-created documentation
<FromGitter> <grkek> so I have to dig in the C headers
<FromGitter> <grkek> for function calls, etc.
<FromGitter> <636f7374> @grkek Yes it's tricky :) But it looks good, especially on macOS.
<FromGitter> <grkek> What did you think of the way my sample looked ?
<FromGitter> <grkek> in my opinion pretty good so far
<FromGitter> <grkek> the macros are tricky but its okay
<FromGitter> <grkek> as long as you dont look into the source code >.>
<FromGitter> <636f7374> nice.
<FromGitter> <636f7374> I have encountered some problems, Hash is sometimes unsafe in threads?
<FromGitter> <grkek> its a tuple :D
<FromGitter> <grkek> you might think it is a hash but in reality it is a tuple
<FromGitter> <grkek> it gets compiled to a tuple
<FromGitter> <grkek> which is weird
<FromGitter> <grkek> and back to hash again
<FromGitter> <636f7374> @grkek Sorry, No, it's the cache part of my DNS resolver.
<FromGitter> <grkek> nice
<FromGitter> <grkek> dns resolver on crystal must be really fast
<FromGitter> <636f7374> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e36ef86e8a83835590fc793]
<FromGitter> <636f7374> @grkek I may want to open an issue asking about the problem of hash in the thread.
<FromGitter> <tenebrousedge> is there some reason to expect Hash to be thread-safe?
<alex``> I face another problem :(, I have now my `Chronic::Range(range)` and `step`, it works great to set `step` to `1.day`, etc. but my end usage would be for the command-line, how can I specify (shell) `chronic-period <format> <begin> <end> <step>` to `chronic-period '%F' '7 days ago' 'tommorow' '1.days'`
<FromGitter> <grkek> It is mutable
<FromGitter> <grkek> so it should not be safe right ?
<FromGitter> <grkek> I am not quite sure
<FromGitter> <636f7374> @grkek Ok my mistake, i should use linked list (LRU)
<alex``> I want `1.day` from the command-line (string) be callable as `1.day` (time span)
<FromGitter> <636f7374> @grkek thank you for your help. :)
<FromGitter> <grkek> oh no problem :D
<alex``> I want to avoid something too verbose like calling `Time.span.new(days: options.days.to_i, hours: options.hours.to_i, etc.)`
<FromGitter> <tenebrousedge> your options are going to generally be kinda verbose
<alex``> I found my command-line chronic-period has too many ordered arguments
<FromGitter> <grkek> well then mr alex mess it up B-)
Dreamer3 has quit [Ping timeout: 268 seconds]
Dreamer3 has joined #crystal-lang
Dreamer3 has quit [Ping timeout: 265 seconds]
JuanMiguel has joined #crystal-lang
JuanMiguel has quit [Remote host closed the connection]
Dreamer3 has joined #crystal-lang
<alex``> https://crystal-lang.org/api/0.32.1/Time/Span.html#new(days:Int,hours:Int,minutes:Int,seconds:Int,nanoseconds:Int=0)-class-method
<alex``> I'm not sure I get by the description; does it mean we can pass `days, hours, minutes, seconds` (not named) on it?
<alex``> because I see default `nanoseconds = 0`
<alex``> > Error: Chronic::Range is not a generic type, it's a class
<alex``> `def self.new(range : Range(Time, Time))`
<alex``> How can I tell `Range` is a type?
<alex``> because of `Chronic::Range` naming :/
<FromGitter> <Blacksmoke16> `::Range` try that
<alex``> Thanks
<alex``> why does it try a class when it's to specify a type?
sagax has quit [Remote host closed the connection]
<FromGitter> <Blacksmoke16> because you're using `Range` within the namespace of your app
<FromGitter> <Blacksmoke16> so its resolving to *YOUR* `Range` type
<FromGitter> <Blacksmoke16> not the stdlibs
<FromGitter> <confact> @grkek it is a example code only. I should probably just move it somewhere else or have it in the Readme.
<alex``> how to handle something that can return multiple type values
<alex``> I hesitate to implement a Chronic.parse(text) to return a Time object or Time range
<FromGitter> <tenebrousedge> there's already `Time.parse`
<alex``> Time.parse 'text' is determined by printf format
<FromGitter> <tenebrousedge> yes
<alex``> I want to guess
<alex``> :X
<alex``> without printf
<FromGitter> <tenebrousedge> good f'ing luck <_< but you'll eventually want to do a case statement to figure out which is which
<alex``> if my parse method can return Time or Time Range, how I can on the receiving handle ambigous type?
<alex``> oki
<alex``> case my_return_value
<alex``> when Time
<alex``> ..
<alex``> when Range(Time,Time)
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e370eddf6945f41ef5505de]
<alex``> ..
<alex``> ?
<FromGitter> <tenebrousedge> I think it uses `is_a?` under the hood, so you can use the class rather than the type
_ht has joined #crystal-lang
<FromGitter> <Blacksmoke16> why not just overload `handle`
<FromGitter> <Blacksmoke16> `handle result`
_ht has quit [Quit: _ht]
_ht has joined #crystal-lang
* FromGitter * tenebrousedge shrugs
JuanMiguel has joined #crystal-lang
JuanMiguel has quit [Read error: Connection reset by peer]
_ht has quit [Quit: _ht]
_ht has joined #crystal-lang
<FromGitter> <andrewc910> Hey everyone, I am finishing up my docs this week for a initial release of my authentication shard. Let me know what you think! https://github.com/andrewc910/contrive
<FromGitter> <andrewc910> Any suggestions are appreciated! This week i am focusing on guides & crystal documentation but will get back to actual development after.
<alex``> what is the best between string.strip.split(/\s*\.\.\s*/).map { |x| x.split(/\s*\+\s*/) }
<alex``> and doing split("..") / split('+') and call strip on each element
<FromGitter> <tenebrousedge> `scan` seems preferable
<alex``> never used it
<alex``> how it is better?
<FromGitter> <tenebrousedge> what's an example input and output here?
<alex``> "2018-12-23 + next week .. tomorrow"
<alex``> want to have the time range with ..
<alex``> and inside I can do math on the date (absolute + relative (from now))
<alex``> for output I think [["2018-12-23","next week"],["tomorrow"]]
<alex``> not sure
<FromGitter> <tenebrousedge> `string.scan(/([\d-]+)[\s+]+(([\w\s]+) \.\. ([\w\s]+))/)`
<alex``> not sure if I should do like that for my tokenizer function
<alex``> if the return value has more than one element, it's a time range
<alex``> otherwise at in the single element, just time
<alex``> tenebrousedge, they can be any string
<alex``> the date string
<alex``> not necessary as strict as YYYY-MM-DD
<FromGitter> <tenebrousedge> you might want to use StringScanner + iterator to tokenize
<alex``> "7 days ago + tomorrow .. next monday"
<alex``> for example
<alex``> the important part split are "+" and ".."
<FromGitter> <tenebrousedge> well
<alex``> (I may doing it wrong)
<FromGitter> <tenebrousedge> is `+` guaranteed to be in the string ?
<alex``> no
<alex``> "yesterday .. next day"
<alex``> "yesterday + tomorrow" (yesterday + 24h)
<FromGitter> <tenebrousedge> using underscores in `next_day` would make your life easier
<alex``> I know :X
<alex``> maybe I can do a pre_normalize
<alex``> to make it easier
<alex``> doing some gsub
<alex``> is it a good intermediate structure to have this output:
<alex``> [["2018-12-23", "tomorrow"], ["tomorrow"]]
<FromGitter> <oren> i want to write a static site generator in crystal. i mainly need to figure out how to convert md to html and also inject a few links and maybe css into the generated html. any pointers?
<FromGitter> <tenebrousedge> do `split('+').map(&.split("..")`
<alex``> on each element I can call the parser to return a time, but I still have one logic with my output, is "does my return data has more than a single value, if yes, timerange, else time"
<FromGitter> <tenebrousedge> @oren https://crystal-lang.org/api/0.21.1/Markdown.html
<FromGitter> <tenebrousedge> hmmm
<FromGitter> <oren> @tenebrousedge oh. interesting
<FromGitter> <tenebrousedge> it was removed
<FromGitter> <tenebrousedge> related https://shards.info/repos/crystallabs/fluence
<FromGitter> <oren> Error: can't find file 'markdown'
<FromGitter> <tenebrousedge> yeah, it was in core in v21
<FromGitter> <tenebrousedge> https://crystalshards.xyz/?filter=markdown
<FromGitter> <Blacksmoke16> `markd`
<FromGitter> <Blacksmoke16> is one you want to use
<alex``> tenebrousedge I fail to see the gain of `string.scan(/([\d-]+)[\s+]+(([\w\s]+) \.\. ([\w\s]+))/)` vs `split("..").map(&.split("+")`
<FromGitter> <tenebrousedge> `scan` could be used if your inputs were saner
<alex``> :(
<FromGitter> <tenebrousedge> it allows you to capture specific elements without needing `strip`
<alex``> I actually used '+' and '..' as separator because I thought it was the simpler x(
<alex``> btw &. chaining with argument is net
<FromGitter> <tenebrousedge> it just means you have to do negative matching (exclusion) rather than positive matching
<FromGitter> <tenebrousedge> and yes, Crystal > Ruby in some respects
<alex``> I'm amazed how crystal tackled ruby quirks in the little details
<alex``> how to handle named arguments, block &->receiver.meth(type), etc.
<FromGitter> <tenebrousedge> named arguments in Ruby are becoming more like Crystal
<alex``> named arguments look like a plug
<alex``> in ruby
<FromGitter> <tenebrousedge> Ruby's equivalent to `&->` has some advantages over Crystal
<alex``> what is ruby requivalent to &-> ?
<FromGitter> <tenebrousedge> you can do `some_arr.map(&an_object.transformation.another.method(:my_method))`
<alex``> it could be nice to have a document Difference with Ruby, how Crystal approched the features when choosing to do differently
<FromGitter> <tenebrousedge> :/
<FromGitter> <tenebrousedge> it would be a small book
<alex``> like class Foo::Bar is possible in Crystal, while in Ruby the module has to be declared first
<alex``> in ruby to not have 2 indent level I have done
<alex``> module Foo; end
<alex``> class Foo::Bar ..
<alex``> hm
<alex``> my result of tokenize(text) is an array(array(string)), the array can have 1 (for time) or 2 values (for time range). given this output, I thought I can define 2 `handle` functions using overloading, with tuple of 1 element, and tuple of 2 elements
<alex``> how can I do that?
<alex``> since I have an array, I guess if I pass `handle(tokens)` it will not work
<alex``> or maybe `handle(...token)` (not sure if `...` work with array
<alex``> it looks cleaner than doing case/when
ur5us has joined #crystal-lang
<FromGitter> <tenebrousedge> a tuple is probably not going to work there, but you can do `handle(tokens)` or `handle(tokens[0], tokens[1])`
<alex``> it doesn't look sweet :(
<alex``> like this?
<FromGitter> <dscottboggs_gitlab> that's exactly right
<alex``> I don't feel satisfied when doing that xd
sagax has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> I always debate whether abstractions over those sorts of things are a bad idea to create, because they would have to be implemented in such a inefficient manner that it creates opportunities to use them without understanding how inefficient it might be to use them.
<FromGitter> <dscottboggs_gitlab> like I could make a macro that you could install as a shard and just do ⏎ ⏎ ```require "array_to_tuple" ⏎ some_array.to_tuple # => tuple of values``` ⏎ ⏎ But is that *the right* abstraction? C++ is full of abstractions, and look where that got it [https://gitter.im/crystal-lang/crystal?at=5e3732933aca1e4c5f5d75ae]
<alex``> that is fair
<alex``> when having an argument named `def handle(time)` `def handle(begin, end)`, do you thing it's better to just `time`, `time : String`, or name the variable differently time_str or something?
<FromGitter> <dscottboggs_gitlab> TBH it's down to personal preference. Crystal type restrictions are a restriction that applies at compile time and doesn't reflect an optimization in the resulting code. So if you want more safety, go for more restrictions. If a method is generic and you think you may send various types to it later, save yourself some debugging time and leave it off
<FromGitter> <Blacksmoke16> could also type restrict an argument to `_`
<FromGitter> <Blacksmoke16> so its clear to other readers that it should accept any types
<FromGitter> <dscottboggs_gitlab> you can write crystal like it's a shell script, and I sometimes do, but if I were creating a huge production app in Crystal I'd insist on every type being annotated as much as possible. It communicates intent which is important for collaboration, but less so for a sub-500 line script that only you're going to use 😂
<FromGitter> <dscottboggs_gitlab> hey there @Blacksmoke16 how's things?
<FromGitter> <Blacksmoke16> going well, hbu/
<FromGitter> <dscottboggs_gitlab> pretty well
<FromGitter> <Blacksmoke16> good to hear
<FromGitter> <dscottboggs_gitlab> ugh what's the deal with ⏎ ⏎ ```Failed to raise an exception: END_OF_STACK ⏎ [0x7f9d25475396] ???``` ⏎ ⏎ stack traces just don't work in static-compile mode? [https://gitter.im/crystal-lang/crystal?at=5e37351cf301780b8360ec61]
<FromGitter> <Blacksmoke16> rip
<alex``> it looks like this currently
<alex``> `handle` belongs to the parser.cr or it should have it own file/class to you? (I'm afraid of circle dependency)
<FromGitter> <tenebrousedge> the `map` and `reduce` in `handle` look like they can be combined
<alex``> definitively yes
<FromGitter> <Blacksmoke16> how would you remove a union of `MyType | Nil.class`?
<alex``> I would do that but I'm experimenting currently
<FromGitter> <Blacksmoke16> remove `Nil` from a `.class` union*
<FromGitter> <tenebrousedge> `unsafe_as`? :/
<FromGitter> <tenebrousedge> hmm, that doesn't do quite the right thing
<FromGitter> <Blacksmoke16> `.as(MyType.class)` i think works
<FromGitter> <tenebrousedge> so you have `(MyType | Nil).class` or `(MyType | Nil)` ?
<FromGitter> <Blacksmoke16> the former
<FromGitter> <tenebrousedge> so you're doing `as` before `class`?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8hzi
<FromGitter> <Blacksmoke16> is what im running into now
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8hzj same with this approach, seems that type restriction should be removed
<FromGitter> <Blacksmoke16> at least until you can use `Enum` in a generic
<FromGitter> <tenebrousedge> so it works unless the type is `Nil`?
<FromGitter> <tenebrousedge> no, it just splodes
<FromGitter> <Blacksmoke16> prob since `type` in this context is `Enum`
<FromGitter> <Blacksmoke16> `self?` in that context is `Enum?`
<FromGitter> <tenebrousedge> I suspect you can't get there from here
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> ogh
<FromGitter> <tenebrousedge> maybe in a macro?
<FromGitter> <Blacksmoke16> `Unhandled exception: Unknown enum Enum value: 0 (Exception)` is what im getting now when i removed those type restrictions
<FromGitter> <dscottboggs_gitlab> https://play.crystal-lang.org/#/r/8hzx
<FromGitter> <dscottboggs_gitlab> this is very frustrating haha https://play.crystal-lang.org/#/r/8hzy
<FromGitter> <Blacksmoke16> Might have to rethink my approach
<FromGitter> <Blacksmoke16> Wanted to avoid reopening the types themselves, but that seems like the best approach
<FromGitter> <Blacksmoke16> Option*
<FromGitter> <dscottboggs_gitlab> 👍
<FromGitter> <dscottboggs_gitlab> monkey-patch it all day
<FromGitter> <Blacksmoke16> If just for deseralization I'd be ok with it I guess
alexherbo24 has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> sometimes there's just no other way to do it
alex`` has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> Always wondered if it's considered a feature or a smell
<FromGitter> <Blacksmoke16> Depends on the context I guess
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo24 is now known as alexherbo2
<FromGitter> <dscottboggs_gitlab> both? haha ⏎ ⏎ Like, probably shouldn't do it, but sometimes it's really helpful. Idk I'm definitely more quick to reach for that kinda stuff than most people.
<FromGitter> <dscottboggs_gitlab> idk it depends on your priorities maybe.
<FromGitter> <dscottboggs_gitlab> there are extremes you can take on both the maintainability and the performance-at-all-costs side
alex`` has joined #crystal-lang
<FromGitter> <Blacksmoke16> Very true
<FromGitter> <oren> so i can use 'marked' to generate html from a markdown file. now the question is what's the best way to inject some html to the generated dom (i want to have a custom HTML header for each index.html page.
<FromGitter> <Blacksmoke16> Another md file?
<FromGitter> <tenebrousedge> a layout file
<FromGitter> <tenebrousedge> for sure
<FromGitter> <tenebrousedge> but I'm not sure what the point of yet another static site generator is
<FromGitter> <oren> @Blacksmoke16 how do i inject one md into another?
<FromGitter> <oren> @tenebrousedge can you elaborate on 'a layout file'? also, i can't find a static site generator that allow me to customize the links expect for Docsify but there is a bug with the nav bar (https://github.com/docsifyjs/docsify/issues/876#issuecomment-557937055)
<FromGitter> <tenebrousedge> just a template file ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e37452c1594133558510b06]
<FromGitter> <tenebrousedge> using the template language of your choice
<FromGitter> <oren> oh. and how do you inject the missing parts?
_ht has quit [Remote host closed the connection]
<FromGitter> <tenebrousedge> you render the template using your template rendering engine
<FromGitter> <tenebrousedge> or, y'know, use `gsub`
<FromGitter> <oren> interesting. i'll look for 'template rendering engine' on https://crystalshards.xyz
<alex``> is there something like friendly-duration in crystal?
<FromGitter> <Blacksmoke16> Pretty sure you can just call humanize
<alex``> humanize for time/time span?
<FromGitter> <tenebrousedge> @oren it looks like there's ports of mustache and slim, among others
<alex``> there is not humanize method for time
<FromGitter> <oren> @tenebrousedge i'll look into this. thanks!
<alex``> https://crystal-lang.org/api/0.32.1/Number.html#humanize(precision=3,separator='.',delimiter=',',*,base=10**3,significant=true,&):String-instance-method
<alex``> I copied the example and reached a bug
<alex``> `when .>=(4)`
<alex``> > You've reached a bug in the playground. Please let us know about it.
<alex``> syntax error in play:9
<alex``> Error: unexpected token: >=
<FromGitter> <tenebrousedge> you can use `4..`
<alex``> what does it mean?
<FromGitter> <tenebrousedge> it's an endless range
<alex``> when do <end> is specifid inf?
<alex``> oki
<alex``> I try to understand how I can use humanize to convert time duration
<alex``> magnitude = number of digits?
<alex``> 12_122, magnitude 5?
<FromGitter> <Blacksmoke16> prob could use that as an example
<FromGitter> <Blacksmoke16> i think you can provide your own magnitudes as well
<FromGitter> <straight-shoota> alex, essentially yes
<FromGitter> <straight-shoota> But `Number#humanize` won't work for formatting time spans
<FromGitter> <oren> i have the content of html file in a variable. i want to create a new file. I don't see it in the docs for the File object - https://crystal-lang.org/api/0.32.1/File.html
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.32.1/File.html#write(filename,content,perm=DEFAULT_CREATE_PERMISSIONS,encoding=nil,invalid=nil,mode=%22w%22)-class-method
<FromGitter> <straight-shoota> alex, there are some shards which might help for your use case: https://github.com/vladfaust/time_format.cr https://github.com/mamantoha/humanize_time
<FromGitter> <Blacksmoke16> er, the one below https://crystal-lang.org/api/master/File.html#writable?(path:Path%7CString):Bool-class-method
<FromGitter> <oren> @Blacksmoke16 thank you