RX14 changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.27.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> <eliasjpr> “True, linux is monolithic, and I agree that microkernels are nicer. With a less argumentative subject, I’d probably have agreed with most of what you said. From a theoretical (and aesthetical) standpoint linux looses. If the GNU kernel had been ready last spring, I’d not have bothered to even start my project: the fact is that it wasn’t and still isn’t. Linux wins heavily on points of being
<FromGitter> ... available now.” ⏎ ⏎ — Linus Torvalds, in a 1992 post on the Usenet group comp.os.minix, responding to a post by MINIX author Andrew S. Tanenbaum that claimed that Linux was already obsolete, in part because it used a more traditional monolithic kernel, in which most basic parts of the operating system are managed within the kernel itself, ... [https://gitter.im/cryst
<FromGitter> ... al-lang/crystal?at=5c79c9c3b1503b3d7065820d]
<FromGitter> <eliasjpr> I find this interesting and wanted to share with the crystal community
jemc has quit [Ping timeout: 268 seconds]
<FromGitter> <whitenoiseoss> that is interesting, I did not know all of that.
<FromGitter> <whitenoiseoss> I used to work at Linux Foundation as a Linux Engineer. My team met Linus!
<FromGitter> <whitenoiseoss> I knew he basically made Linux in a hurry to make something "available now"
<FromGitter> <whitenoiseoss> but didn't know about the kernel debate
<FromGitter> <whitenoiseoss> i have to run off and cook dinner for the wife and such, but when i get back
<FromGitter> <whitenoiseoss> i plan on starting a very informative discussion around immutable vs mutable data types and when you use them or if at some point you're doing safety tradeoffs for speed and how Crystal interacts with this space.
<FromGitter> <whitenoiseoss> mostly for my own education, as I am not an expert on such and I bet there are some in here.
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter> <dscottboggs_gitlab> https://www.reddit.com/r/crystal_programming/comments/awcp0p/is_there_a_way_crystal_can_produce_binary/ ⏎ ⏎ Is there no way to `require` a compiled shard? I haven't tried but I assumed that was the purpose of `crystal init lib` -- to create a library that can be compiled and used in apps.
<FromGitter> <fridgerator> No
<FromGitter> <dscottboggs_gitlab> oh my
return0e has joined #crystal-lang
return0e_ has quit [Ping timeout: 258 seconds]
jemc has joined #crystal-lang
jemc has quit [Quit: WeeChat 2.2]
<FromGitter> <whitenoiseoss> you mean like a shared library?
<FromGitter> <whitenoiseoss> .so and all that
<FromGitter> <whitenoiseoss> yeah, Crystal doesn't do that.
f1refly has quit [Ping timeout: 264 seconds]
f1refly has joined #crystal-lang
Dreamer3 has joined #crystal-lang
Dreamer3 has quit [Quit: Leaving...]
okami has left #crystal-lang [#crystal-lang]
_whitelogger has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e_ has joined #crystal-lang
<FromGitter> <r00ster91> is it possible to trap IOT with signal 6? I have `Signal::IOT.trap { puts "IOT" }` on the top of my program but I never get the output "IOT". I only get `Program received and didn't handle signal IOT (6)` when I get the signal
<FromGitter> <r00ster91> is someone able to trap it?
azuri5 has joined #crystal-lang
return0e has joined #crystal-lang
return0e_ has quit [Ping timeout: 255 seconds]
flaviodesousa has joined #crystal-lang
_whitelogger has joined #crystal-lang
laaron has quit [Read error: Connection reset by peer]
laaron has joined #crystal-lang
ternarysolo has joined #crystal-lang
ternarysolo has quit [Ping timeout: 245 seconds]
ashirase has quit [Ping timeout: 246 seconds]
ashirase has joined #crystal-lang
marmotini_ has joined #crystal-lang
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
lucasb has joined #crystal-lang
_whitelogger has joined #crystal-lang
marmotini_ has quit [Remote host closed the connection]
_whitelogger has joined #crystal-lang
cyberarm has quit [Ping timeout: 250 seconds]
cyberarm has joined #crystal-lang
Gasher has joined #crystal-lang
<Gasher> hi, do you have any examples of this method? I'm not sure how to use it
<Gasher> http://crystal-lang.github.io/crystal-db/api/0.5.1/DB/ResultSet.html#read%28type%3ADB%3A%3AMappable.class%29-instance-method
<Gasher> it's not there @Blacksmoke16
<FromGitter> <Blacksmoke16> `puts "#{rs.read(String)} (#{rs.read(Int32)})"`
<FromGitter> <Blacksmoke16> thats not ti?
<Gasher> nope, there are multiple read methods
<Gasher> 5 actually
<FromGitter> <dscottboggs_gitlab> overloads?
<Gasher> yeah
<FromGitter> <Blacksmoke16> id vote its used for the DB.mapping macro
<FromGitter> <dscottboggs_gitlab> You're supposed to use the overload for the type expected. so if the column you're trying to read is a text type then you would use `rs.read String`, if it's an Integer type, you'd use `rs.read Int32`, etc
<Gasher> yeah
azuri5 has quit [Quit: azuri5]
<Gasher> but there is another one for types
<Gasher> underneath
<FromGitter> <dscottboggs_gitlab> oh, the last one, with the `*`?
<Gasher> there is def read(type : T.class) : T forall T
<Gasher> #
<FromGitter> <dscottboggs_gitlab> so if you had a int column, a text, and another integer, in that order, you could do ⏎ ⏎ ```first, second, third = rs.read Int32, String, Int32``` [https://gitter.im/crystal-lang/crystal?at=5c7aa1bf4a65f754735155ca]
<Gasher> which I assume is in the example on GH
<Gasher> but I mean the one above, with DB::Mappable.class
<FromGitter> <dscottboggs_gitlab> pj
<Gasher> is there a way to nicely put all the columns in an object/dictionary/whatever it's called in Crystal?
<FromGitter> <dscottboggs_gitlab> yes, there is, @Blacksmoke16 do you have an example available for using DB::Mapping? I'm looking around...
<FromGitter> <dscottboggs_gitlab> yeah I just was about to link to that
<Gasher> that's super neat actually, what I was looking for
<Gasher> thanks
<FromGitter> <Blacksmoke16> np
<FromGitter> <dscottboggs_gitlab> in the docs http://crystal-lang.github.io/crystal-db/api/0.5.1/DB.html#mapping%28properties%2Cstrict%3Dtrue%29-macro
<Gasher> oh, didn't see that
<FromGitter> <dscottboggs_gitlab> yeah it's down a little ways.
<FromGitter> <dscottboggs_gitlab> i didn't see it at first either
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
azuri5 has joined #crystal-lang
azuri5 has quit [Client Quit]
azuri5 has joined #crystal-lang
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
<FromGitter> <bajro17> Hello :)
<FromGitter> <bajro17> I want ask how I can name websocket conneection
<FromGitter> <bajro17> ```HTTP::WebSocketHandler.new do |socket| ⏎ puts "Socket opened" ⏎ SOCKETS << socket``` [https://gitter.im/crystal-lang/crystal?at=5c7aad54c1cab53d6f63e0f7]
<FromGitter> <dscottboggs_gitlab> o/
<FromGitter> <dscottboggs_gitlab> Make `SOCKETS` a Hash instead of an Array?
<FromGitter> <bajro17> how to have when someone enter page to enter his name and to I give socket name
<FromGitter> <bajro17> I know this
<FromGitter> <bajro17> but how to get name then?
<FromGitter> <dscottboggs_gitlab> a URL parameter or header, would be ideal no?
<FromGitter> <bajro17> hmmmm
<FromGitter> <bajro17> URL parameter sound good
<FromGitter> <bajro17> Thank you so much @dscottboggs_gitlab I will try now this :)
<FromGitter> <dscottboggs_gitlab> sure
<FromGitter> <vladfaust> @bajro17 if you want to safely parse the URL params, then you might like this: https://docs.onyxframework.org/rest/channels.html#errors
<FromGitter> <bajro17> @vladfaust is that your framework?
<FromGitter> <vladfaust> That is my framework
<FromGitter> <bajro17> I like it bro
<FromGitter> <bajro17> also you do so good documentation I like how is easy to find stuff on side
<FromGitter> <vladfaust> Oh, thanks! They are still in progress, though
<FromGitter> <vladfaust> But REST essentials seem to be well-described
Yxhuvud has quit [Quit: No Ping reply in 180 seconds.]
wakatara has joined #crystal-lang
<FromGitter> <vladfaust> Also https://blog.onyxframework.org/posts/distributed-websocket-chat-in-40-loc/ does exactly what you want -- naming chat participants
<wakatara> I'm new to Crystal (from Ruby) after reading the Crystal lang book but am having trouble bending types to my will. I tryingt to read a yaml file (an array of hashes) and then force it into either an array of Hashes or a struct of the form string:int64 but failing miserbly. I would have thought a simple thing << yaml.parse(path) would have sufficed but keep getitng told the overload operator doesn't work that way. I'm assuming this is
<wakatara> a typesafe thing, but is there a good way to do this? (that doesn't involve me setting the property value on each element?).
<FromGitter> <Blacksmoke16> got a playground link?
<wakatara> Blacksmoke16: was that directed at me?
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> might be worth taking a look at https://crystal-lang.org/api/0.27.2/YAML/Serializable.html
lucasb has quit [Quit: Connection closed for inactivity]
<FromGitter> <dscottboggs_gitlab> @wakatara https://play.crystal-lang.org/ or https://carc.in/
<wakatara> Blacksmoke16: I have been looking at that, but it unfortuantely does not seem to be supporting my use case (using yaml as a config file where each of the keys are their own unique property. The yaml file is used as a config file for an array of habits with a defined period - As an exercise i'm reimplmenting habitctl in crystal.)
<FromGitter> <dscottboggs_gitlab> OH I know what you're trying to do
<FromGitter> <dscottboggs_gitlab> You have a set of unique keys mapped in yaml to a set of predefined-structure objects, no??
<FromGitter> <Blacksmoke16> prob could use the `read_file` macro
<FromGitter> <dscottboggs_gitlab> So you would need to define a YAML::Serializable struct/class then you want to try `Hash(String, MySerializable).from_yaml(contents)`
<wakatara> Yes, that is basically the idea. Playground link for clarity: https://play.crystal-lang.org/#/r/6eec
<wakatara> The yaml just seemed to be an easy way to make the config file, but if I have to write something tricky, I could use a straight up text file to split the hash and just feed them into the array.
<FromGitter> <Blacksmoke16> yea so you're running into a type error obs
<wakatara> Out of curiosity though, even with a straight Array of {String => Int64} though, why does the << overload operator not work to push the maps into the array?
<FromGitter> <Blacksmoke16> your array has a type of `Array(Hash(String.class, Int64.class))` when you're trying to push `YAML::Any` into it
<FromGitter> <Blacksmoke16> i.e. you would have to push a Hash of `String.class => Int64.class` to it
<FromGitter> <Blacksmoke16> which i dont think is what you want
<wakatara> Baclksmoke16: Right, so how do I convert the YAML::Any to that Hash format to pour it ito the waiting array? (and sorry if this sis a stupid question)
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.27.2/YAML/Any.html#as_i64%3AInt64-instance-method
<FromGitter> <Blacksmoke16> are methods for `Any`, that you would have to use to convert it to the given type
<FromGitter> <Blacksmoke16> or maybe do something similar to what @dscottboggs_gitlab suggested
<FromGitter> <Blacksmoke16> do you have a sample of the contents of the yaml file?
<wakatara> Alrighty. Will try that. Thank you very much for the pointers!
<FromGitter> <dscottboggs_gitlab> I'm coming up with a playground link to help you @wakatara
<wakatara> (that is super kind of you. Thank you.)
<FromGitter> <dscottboggs_gitlab> oh god.... don't hit escape while in the playground 😦
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <dscottboggs_gitlab> just lost my progress
<FromGitter> <Blacksmoke16> ctrl+z
<FromGitter> <dscottboggs_gitlab> nope it left the editor page
<FromGitter> <Blacksmoke16> :(
ua_ has joined #crystal-lang
ua has quit [Ping timeout: 244 seconds]
<FromGitter> <dscottboggs_gitlab> there we go @wakatara https://play.crystal-lang.org/#/r/6een
<wakatara> Taking a look... brb
<wakatara> Ah, gotcha! Thnak you! (I"m assuming there is no eay to serialize without naming the properties in the yaml directly then though, correct? My original idea had been to simply have a file like habits: with a - eat daily: 1 type thing on it.
<wakatara> Seriously though, this is super helpful> I can move forward with the other logic and come back to the file load issue later.
<FromGitter> <dscottboggs_gitlab> That would just be a `Hash(String, Array(Hash(String, Int32)))` -- if it's so predictable
<FromGitter> <dscottboggs_gitlab> also making a property nullable (I.E. the type ends in `?`) means you can leave it out...
<wakatara> Very helpful. Thank you... I will play around with it some more, get the basic working and swing back to it. thank you!!!
<FromGitter> <dscottboggs_gitlab> have fun :)
<wakatara> (that YAML_TEXT = <<- YAML ... YAML alone os majorly helpful.)
<FromGitter> <dscottboggs_gitlab> yeah heredocs are nice
azuri5 has quit [Quit: azuri5]
<FromGitter> <whitenoiseoss> does anyone have an example of sanitizing to_json? Let's say you have an "Account" class that has things like password, UUID, or other data that you don't want to export in the JSON object. How do you tell it not to dump certain things?
<FromGitter> <whitenoiseoss> sort of like the `json: "-"` in Go
<FromGitter> <Blacksmoke16> do you care that that field wouldnt get read on `from_json`?
<FromGitter> <whitenoiseoss> hm. I don't have anything specific in mind, so let's say no on this one.
<FromGitter> <whitenoiseoss> I think in most cases (like a password hash) you would receive the password from some sort of input, you wouldn't just blindly make a User object from the JSON
<FromGitter> <whitenoiseoss> so yeah, that should be fine
<FromGitter> <Blacksmoke16> are you using `JSON::Serializeable`?
<FromGitter> <whitenoiseoss> no, I was just playing with JSON.mapping
<FromGitter> <Blacksmoke16> then just do `ignore: true`
<FromGitter> <Blacksmoke16> that should work
<FromGitter> <whitenoiseoss> oh look!
<FromGitter> <whitenoiseoss> JSON::Serializeable does exactly what I want
<FromGitter> <Blacksmoke16> yea, then could just add `@[JSON::Field(ignore: true)]`
<FromGitter> <whitenoiseoss> yeah, nice, cool
<FromGitter> <whitenoiseoss> I was only seeing JSON.mapping( <all fields> )
<FromGitter> <whitenoiseoss> and was like "hmm...this is lacking a lot of options"
<FromGitter> <Blacksmoke16> https://github.com/Blacksmoke16/CrSerializer/tree/master/docs might also be helpful
<FromGitter> <Blacksmoke16> is built upon the serializeable stuff, just adds some extra features
mamantoha has joined #crystal-lang
<FromGitter> <vivus-ignis> hello good people! ⏎ could you please review my first tiny shard please? ⏎ https://github.com/vivus-ignis/crystal-untar ⏎ would appreciate any feedback [https://gitter.im/crystal-lang/crystal?at=5c7acb2b8a7def0752016293]
mamantoha has quit [Ping timeout: 268 seconds]
mamantoha has joined #crystal-lang
azuri5 has joined #crystal-lang
azuri5 has quit [Client Quit]
mamantoha has quit [Quit: Konversation terminated!]
mamantoha has joined #crystal-lang
mamantoha has quit [Client Quit]
mamantoha has joined #crystal-lang
mamantoha has quit [Client Quit]
mamantoha has joined #crystal-lang
<FromGitter> <j8r> nice!! I was searching a library like this to extract tar.gz for so long
<FromGitter> <j8r> there was https://github.com/jwaldrip/tar.cr - but inactive
<FromGitter> <j8r> @vivus-ignis you don't need a subdirectory `src/untar/`
<FromGitter> <j8r> why are you monkey-patching stdlib `Dir` to add self.tempdir?
mamantoha has quit [Ping timeout: 245 seconds]
<FromGitter> <j8r> there is https://crystal-lang.org/api/0.27.2/Dir.html#tempdir%3AString-class-method
<FromGitter> <vivus-ignis> @j8r re: monkey-patching it was just first idea that came to mind. is it considered a bad practice?
<FromGitter> <vivus-ignis> i see what you mean
<FromGitter> <j8r> here this isn't needed (see above link) :)
<FromGitter> <vivus-ignis> it is needed, but probably not as an extension to Dir
<FromGitter> <vivus-ignis> Dir.tempdir from stdlib just returns a default temp directory
<FromGitter> <vivus-ignis> i needed something like File.tempfile, but for directories
<FromGitter> <vivus-ignis> like `mktemp -d` in bash
<FromGitter> <vivus-ignis> but now i'm shadowing the standard Dir.tempdir
<FromGitter> <vivus-ignis> definitely has to be fixed
<FromGitter> <j8r> i see
<FromGitter> <j8r> you have an overload so it's fine
<FromGitter> <vivus-ignis> ah right because of the parameter
<FromGitter> <vivus-ignis> but it's confusing still
<FromGitter> <vivus-ignis> gonna change that
<FromGitter> <vivus-ignis> thank you!
<FromGitter> <j8r> @vivus-ignis you can use https://crystal-lang.org/api/0.27.2/File.html#tempname(prefix%3AString%3F%2Csuffix%3AString%3F%2C*%2Cdir%3AString%3DDir.tempdir)-class-method
<FromGitter> <j8r> then create a directory with this
<FromGitter> <vivus-ignis> oh nice
<FromGitter> <j8r> maybe you can have `src/libtar.cr` for the binding, a bit like https://github.com/crystal-lang/crystal/tree/master/src/lib_z
sz0 has joined #crystal-lang
<FromGitter> <j8r> then if you want to better organize the binding, having `src/libtar/...`
<FromGitter> <j8r> or `lib_tar`.. whatever 😄
laaron has quit [Quit: ZNC 1.7.1 - https://znc.in]
laaron has joined #crystal-lang
<FromGitter> <vivus-ignis> good point
sagax has joined #crystal-lang
<wakatara> When you have an array of structs, you cannot simply append to them in a form like array[2] = Struct.new(this, that)?
<FromGitter> <j8r> why array of a given struct would differ with an array of a given class?
<wakatara> I am confused as to why I'm seeing the error : undefined method '[]=' for Array(Harsh::Habit).class
<FromGitter> <j8r> do you forgot the `.new`?
<wakatara> effectively I have habits = Array(Habit), but habuts doesn't seem to like the << or the []= being used for it if it was simply a standard type
<wakatara> habits[line] = Habit.new(name = habit[0], every = habit[1].to_i)
<wakatara> in a block
<FromGitter> <maiha> `habits = Array(Habit).new`
lucasb has joined #crystal-lang
<wakatara> Doh. It is obviously time to call it a night. Thank you maiha:
<wakatara> works fine now.
<FromGitter> <j8r> @vivus-ignis hum. usually you have `src/mymodule.cr` that has `require "./mymodule/*"`
<FromGitter> <vivus-ignis> i wanted it to be bit more explicit
<FromGitter> <j8r> but what the point of `src/lib_tar/lib_tar`? Isn't redundant?
<FromGitter> <j8r> you can have `src/lib_tar/types.cr`, `src/lib_tar/header.cr`
<FromGitter> <j8r> the error handling in https://github.com/vivus-ignis/crystal-untar/blob/master/src/untar.cr is not standard
<FromGitter> <vivus-ignis> well it's like in an example you've shared https://github.com/crystal-lang/crystal/tree/master/src/lib_z
<FromGitter> <vivus-ignis> re: error handling. that's why i've asked for help here =)
<FromGitter> <j8r> oh, yes
<FromGitter> <j8r> haha
<FromGitter> <j8r> not really the best example so
<FromGitter> <j8r> binding of libclang
<FromGitter> <j8r> @vivus-ignis you error handling remind me https://github.com/j8r/error.cr
<FromGitter> <j8r> but better using it in applications, not in libaries
<FromGitter> <vivus-ignis> this is a more feature-full thing, your error library. i thought of something that is a bit more than "not a nil" =))
<FromGitter> <j8r> absolutely, this meant for apps - not libs like this
<FromGitter> <j8r> you can also return nil @vivus-ignis
<FromGitter> <vivus-ignis> i return nil if there's no error, and that dumb Error object if something's wrong
<FromGitter> <vivus-ignis> so the general consensus is to use exceptions right?
<FromGitter> <vivus-ignis> for crystal
<FromGitter> <j8r> yes
<FromGitter> <vivus-ignis> ok
<FromGitter> <j8r> I don't think it has to return an IO https://github.com/vivus-ignis/crystal-untar/blob/master/src/untar.cr#L72
<FromGitter> <j8r> just extract the file where we want, like the command line
<FromGitter> <j8r> by having like https://crystal-lang.org/api/0.27.2/FileUtils.html#cp_r(src_path:String,dest_path:String)-instance-method `dest_path` and `src_path`
<FromGitter> <vivus-ignis> the idea was to be able to get a file and immediately do something with it
<FromGitter> <vivus-ignis> like an example in the docs
wakatara has quit []
<FromGitter> <j8r> is it mostly a duplicate of https://github.com/vivus-ignis/crystal-untar/blob/master/src/untar.cr#L29 ?
<FromGitter> <j8r> but we know where the file is, it just does a File.read for us??!!
<FromGitter> <vivus-ignis> yes =)
<FromGitter> <vivus-ignis> if i replace my error handling with exceptions, it will be easier to chain this thing
<FromGitter> <j8r> the way you have done is less efficient than `File.open`
<FromGitter> <vivus-ignis> i needed to load an extracted file somewhere to memory
<FromGitter> <vivus-ignis> File.open just gives a file descriptor, right?
<FromGitter> <j8r> which is an IO, yes
<FromGitter> <j8r> but we have to close it
<FromGitter> <vivus-ignis> ah, right
<FromGitter> <j8r> there must be a better way to organize this
<FromGitter> <vivus-ignis> let me reconsider it. but now i have to finish watching "Vice" =)
<FromGitter> <vivus-ignis> thank you, @j8r !
<FromGitter> <j8r> @vivus-ignis is it possible not to have files at all in the IO overload?
<FromGitter> <j8r> like `Tar.extract...` to an IO?
<FromGitter> <vivus-ignis> i think it's possible if i redefine handler functions in libtar
<FromGitter> <j8r> because passing by intermediary temp files is weird, I would be surprised if libtar only deal with files
udiudi has joined #crystal-lang
flaviodesousa has quit [Read error: Connection reset by peer]
udiudi has quit [Quit: Textual IRC Client: www.textualapp.com]
hightower2 has joined #crystal-lang
DTZUZU has quit [Quit: WeeChat 2.2]
lvmbdv has quit [Ping timeout: 244 seconds]
DTZUZU has joined #crystal-lang
<FromGitter> <arnavb> Wait how do I check if a hash contains a key? I'm trying `.includes?` but that always returns false.
<FromGitter> <dscottboggs_gitlab> `#has_key?`
<FromGitter> <arnavb> wait then what does .includes? do
<FromGitter> <dscottboggs_gitlab> uh...lemme check
<FromGitter> <arnavb> This issue came up for me when I was doing crystal spec with contains. Is there an equivalent for `has_key?`? Not sure why `includes?` doesn't have the same behavior...
lvmbdv has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> ok.. so `#includes?` is inherited from `Enumerable`... so to use `includes?` (and hence `should contain`) you have to do it like this... https://carc.in/#/r/6egi
<FromGitter> <dscottboggs_gitlab> so it looks for the pair, not either the key nor the value
lvmbdv has quit [Remote host closed the connection]
<FromGitter> <j8r> @arnavb as @dscottboggs_gitlab shows, an hash element is both a key and a value.
<FromGitter> <j8r> Maybe we might have in the future `Hash#includes?(element : Tuple(K, V))`
lvmbdv has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> just to document it?
<FromGitter> <j8r> Note there is also `#has_value?` as well
<FromGitter> <arnavb> Gotcha. I feel like the docs should have been clearer about this.
<FromGitter> <dscottboggs_gitlab> I agree they definitely could be
<FromGitter> <j8r> It's not really documented
<FromGitter> <j8r> For hash
<FromGitter> <Sija> @arnavb usually you want to check for the either, key or the value, to check both at once you can do `hash[key]? == value`
<FromGitter> <Sija> noone rly uses `Hash#includes?` I guess that's why it's not documented
<FromGitter> <dscottboggs_gitlab> I think the confusion arose more from the `contain` spec macro
<FromGitter> <arnavb> ^
<FromGitter> <Sija> just because it's `Enumerable` it doesn't mean all its methods are in perfect sync with the class implementing it (although they should work - and they do)
<FromGitter> <Sija> and it *is* documented quite clearly - `Enumerable({K, V})`
<FromGitter> <dscottboggs_gitlab> I'm not sure I would agree that that's super clear, it's kinda hard to find if you're new to the language.
<FromGitter> <Sija> once you know the language it is, but for the newcomers might be pretty cryptic indeed
<FromGitter> <dscottboggs_gitlab> I think it would be cool if there were a way to do like `.should contain key: "some key"` or `.should contain value: "some value"`
<FromGitter> <Sija> 👍
<FromGitter> <Sija> agreed, was looking for that too some time ago, ended up doing `hash[key].should eq(value)`
<FromGitter> <Sija> 2 hrs of horse riding (after some considerable break) made me walking like a drunk sailor who just came off the ship :D signing off to lay my corpse onto some soft, cushy riprap, have a gnight guys!
<FromGitter> <dscottboggs_gitlab> good night @Sija
<FromGitter> <dscottboggs_gitlab> @Sija @arnavb @j8r #7497 fingers crossed
<FromGitter> <Sija> @dscottboggs_gitlab I'd rather use `contain({ "key" => "value" })` notation
<FromGitter> <dscottboggs_gitlab> you could still do that in my recommended change
<FromGitter> <dscottboggs_gitlab> it would still act the same unless you specified the `key` or `value` parameters
<FromGitter> <Sija> IMHO it doesn't make much sense to check for the key or value alone since this can be already easily achieved by using `hash.has_key?` and `hash.has_value?`
<FromGitter> <Sija> without a need for refactoring
<FromGitter> <Sija> the only case which is not cover is checking for both at once and usually for more than one KV pair
<FromGitter> <dscottboggs_gitlab> yeah but in specs that would be `hash.has_key?("some key").should be_true` which is nowhere near as nice
<FromGitter> <Sija> nice is… subjective ;) for me it's pretty readable and clear
<FromGitter> <dscottboggs_gitlab> fair enough.
<FromGitter> <Sija> that's what this methods are for in the end...
<FromGitter> <Sija> for single KV pair you can do `hash[key]?.should eq(value)`
<FromGitter> <Sija> it's enough
<FromGitter> <dscottboggs_gitlab> just thought I'd raise the suggestion, I'm pretty sure that's not something the core devs would be a fan of.
<FromGitter> <dscottboggs_gitlab> I agree about checking for a pair.
<FromGitter> <Sija> only case which is troublesome would be checking for a subset like `contains({ "key1" => "value1", "key2" => "value2" })`
<FromGitter> <dscottboggs_gitlab> but if you want to check for a key I think `contain key:` would be nicer
<FromGitter> <dscottboggs_gitlab> yeah I wonder if that would work...
<FromGitter> <Sija> IMO that's overcomplicating it
<FromGitter> <Sija> I wouldn't be sure what's *key* in this case
<FromGitter> <Sija> is it key named *key*?
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/6egl
<FromGitter> <dscottboggs_gitlab> I meant `contain key: "key value"`
<FromGitter> <Sija> I know but that's not rly clear
<FromGitter> <dscottboggs_gitlab> pretty clear that's a named argument, IMO
<FromGitter> <Sija> … which is a named tuple
<FromGitter> <dscottboggs_gitlab> oh... I see your confusion...
<FromGitter> <dscottboggs_gitlab> ugh :(
<FromGitter> <Sija> yeah, using `contain` with a `Hash` argument is pretty clear what's happening
<FromGitter> <dscottboggs_gitlab> but that doesn't work either haha
<FromGitter> <Sija> atm no, that's the point ;)
<FromGitter> <dscottboggs_gitlab> I think you could get it to work by adding a `#includes?(subset : Hash(K, V)` overload to Hash
<mps> Sija: '=>' looks like assignment operator, to me at least
<FromGitter> <Sija> @mps well, that's how `Hash` KV pairs are structured
<FromGitter> <Sija> I ain't doin' anything fancy here