jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <Blacksmoke16> mm
<FromGitter> <Blacksmoke16> dunno, have you tried it?
<oprypin> no doesnt work https://carc.in/#/r/9hvi
deavmi has quit [Ping timeout: 246 seconds]
<FromGitter> <Blacksmoke16> looks like you cant define define a `bar?=` method
<FromGitter> <Blacksmoke16> cant even*
<oprypin> well yea i wasnt trying to do that
<FromGitter> <Blacksmoke16> i know, but was thinking if you had one it would work, as it was complaining it doesnt exist
<oprypin> im quite sure we have `foo[bar]? ||= x` to do `foo[bar]? || (foo[bar] = x)`
deavmi has joined #crystal-lang
<oprypin> wow i'm still suffering so greatly from not being able to collect the expressions over all the calls of a macro
<FromGitter> <Blacksmoke16> 😢
<FromGitter> <wyhaines> @j8r msgpack only supports a very limited number of types in the protocol, and those types describe what is actually passed, so type unions don't really make sense there.
<FromGitter> <wyhaines> It might be instructive to look at the currently msgpack implementation for Crystal. It's fairly easy to follow how the code works and what it does. It has a few implementation details that, IMHO, could be better, and it is unfortunately incredibly slow to use as-is to read msgpack'd data off a socket and reconstitute it into objects, but how it works may help you.
<FromGitter> <wyhaines> I am using it extensively to serialize/deserialize data to/from sockets, but I bypass it's own code for socket handling and do that all myself.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/9hw6 is this expected to be false?
HumanG33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 246 seconds]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 256 seconds]
chachasmooth has quit [Ping timeout: 272 seconds]
chachasmooth has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 256 seconds]
HumanG33k has joined #crystal-lang
duane has quit [Quit: Lost terminal]
duane has joined #crystal-lang
<FromGitter> <dukeraphaelng> Hi guys. Im new to the channel. Wondering if theres any spider-gazelle example apps out there where I can take a look.
<FromGitter> <Blacksmoke16> not that i know of
duane has quit [Ping timeout: 240 seconds]
<FromGitter> <Blacksmoke16> prob be fine to just set it up and try it out
<FromGitter> <jwaldrip> Thanks @Blacksmoke16
<FromGitter> <jwaldrip> ill look into admiral son
<FromGitter> <Blacksmoke16> 👍
zorp has quit [Ping timeout: 264 seconds]
<FromGitter> <imeraj_gitlab> anyone using jennifer with amber framework?
<raz> i use jennifer but not with amber
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 240 seconds]
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
postmodern has joined #crystal-lang
<FromGitter> <j8r> argh too bad lots of errors are defined in the top level
<FromGitter> <j8r> in the stdlib, instead of `Error::OverFlow`, everything is like `OverFlowError` :/
<FromGitter> <j8r> or scoped like `Number::OverFlowError`, `System::Error`
alexherbo24 has joined #crystal-lang
<postmodern> when should you use an enum vs symbols? what is "the crystal way"?
<FromGitter> <j8r> enums
<FromGitter> <j8r> if you have a list of symbols which shares a common ground, make an enum of them
<FromGitter> <j8r> for example in the stdlib: http status codes, parser tokens , etc
<FromGitter> <j8r> symbols are very rarely the Crystal way
<FromGitter> <naqvis> Enums are type-safe while Symbols aren't
<FromGitter> <j8r> true, that's why symbols vs string are similar - except for perf, which can be marginal
<FromGitter> <j8r> I mean, in the utilisation
_whitelogger has joined #crystal-lang
<raz> and symbols remain one of my least fav little details :p
<raz> but gladly they can often be avoided, sadly not always
<postmodern> grumble "Exception: passing a closure to C is not allowed"
<postmodern> it seemed to compile before wiith &block : Callback, but when i replaced Callback with its explicit fully expanded type, i get that error
<postmodern> looks like i have to finally use that Box trick
<postmodern> hmm boxing the callback doesn't fix it
<FromGitter> <naqvis> postmodern can you share example code?
<FromGitter> <naqvis> https://crystal-lang.org/reference/syntax_and_semantics/c_bindings/callbacks.html ⏎ section: Passing a closure to a C function
<postmodern> i'm using to_unsafe to return a proc literal to the .call method, which unboxes the user given in closure
<FromGitter> <naqvis> and what is the error you are getting?
duane has joined #crystal-lang
<postmodern> naqvis, "Error: passing a closure to C is not allowed" from src/extractor.cr:55:63 in 'extract'
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
<FromGitter> <naqvis> sorry code is too much, but I believe https://github.com/postmodern/extractor.cr/blob/7eae335aee826b250683b161574345552c5fd45a/src/extractor.cr#L62 is the culprit, as you are passing local variable
<FromGitter> <naqvis> you will have to ensure that you pass class level member to call-back
<FromGitter> <naqvis> as ivar might get gced before c get a chance to call back
<postmodern> naqvis, hmm in this example, the C library immediately calls the callback before it returns
<FromGitter> <naqvis> but compiler is unable to know or infer that, all compiler see is a call-back
<FromGitter> <naqvis> you can try to add a cvar and then try to pass that on line 55
<postmodern> Error: undefined method 'callback' for Nil (compile-time type is (Extractor::MetadataProcessor | Nil))
<postmodern> arg have to somehow guard against a Nil @@processor. `if @@processor` nor `@@processor && @@processor.callback` doesn't work
coderobe has quit [Quit: Ping timeout (120 seconds)]
coderobe has joined #crystal-lang
<FromGitter> <naqvis> if you are sure arg is going to be not nil then try `@@processor.not_nil!.callback`
<postmodern> well that worked, but still getting the closure error when storing into @@processor
csaba has quit [Ping timeout: 256 seconds]
csaba has joined #crystal-lang
<FromGitter> <asterite> where is `extract_from` called?
<FromGitter> <asterite> findings is being closured, that's the problem
<postmodern> dang, this throws a bit of a wrench into the API, as closures are used to receive the extracted metadata
<FromGitter> <yorci> Hi
<FromGitter> <yorci> How can i set `to_json` method's generated keys as my struct properties?
<FromGitter> <yorci> i mean https://carc.in/#/r/9hy5
<FromGitter> <Blacksmoke16> define your own `to_json` metheod, serializable doesnt allow you to have different keys
<FromGitter> <Blacksmoke16> there are some shards that allow for more functionality
<FromGitter> <asterite> postmodern: you need to save the closure in a class variable or list, then pass a non-closure to the C code that uses that saved closure
<postmodern> i think i got it
<postmodern> i made the main proc a constant that simply unpacks the boxed closure ptr passed to it. then wrap the given closure in a box. specs are now actually running
<FromGitter> <yorci> @Blacksmoke16 thank you
<postmodern> hmm does crystal's YAML impementation not automatically decode `!binary |-` blocks? specs are showing base64 encoded string, when it should be a hex escaped string
renich has joined #crystal-lang
<FromGitter> <Blacksmoke16> prob just wasnt implemented?
<postmodern> Blacksmoke16, looks like some varient of it is supported https://github.com/crystal-lang/crystal/blob/master/src/yaml/schema/core.cr#L277-L278
<FromGitter> <Blacksmoke16> uses base64 tho?
<postmodern> yeah, looks like the short-hand of the tag isn't supported https://yaml.org/type/binary.html
Human_G33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 256 seconds]
renich has quit [Remote host closed the connection]
<postmodern> !!binary seems to work though and returns a Bytes slice
<FromGitter> <naqvis> postmodern seems YAML parser supports the canonical format, but not the generic format ⏎ https://play.crystal-lang.org/#/r/9hy8
zorp has joined #crystal-lang
<FromGitter> <naqvis> might be `libyaml` version limitations
<postmodern> ah weird using Bytes in the type signature unlocks !!binary, but not !binary. Using String ignores both !binary and !!binary
<postmodern> also curious that certain methods have arbitrary default sizes https://crystal-lang.org/api/0.35.1/String.html#build(capacity=64,&):self-class-method
<postmodern> File.read has a default read length of 256, but Strin.build has a default capacity of 64. feels like the default sizes need to be documented why they were choosen
<FromGitter> <naqvis> agree, *magic numbers* should documented
postmodern has quit [Quit: Leaving]
andremedeiros has quit [Quit: ZNC 1.8.1 - https://znc.in]
andremedeiros has joined #crystal-lang
woodruffw has quit [Ping timeout: 260 seconds]
<FromGitter> <tvw> I need a hint on how to tackle the following problem: I have objects of classes like Cat, Dog, Bird which are subclasses of Animal. All animals have names and I want to store all animal objects in a collection class Pets which has a method find_by_name(name) which should return the animal with the given name, no matter whether it is a Cat, Dog or Bird. While this is dead easy in Ruby in Crystal I have to declare an
<FromGitter> ... Array or Hash for a specific type (while I have many types I want to store) and even the method find_by_name(name) must have a specific return type while the collection can hold any type. I have no idea how to handle this simple problem.
<FromGitter> <Blacksmoke16> wouldnt it just be `Array(Animal)`?
<FromGitter> <Blacksmoke16> or something along those lines
<FromGitter> <tvw> As far as I understand, then it just returns objects of the base class, which means, the objects do not respond to the methods the subclasses have but the base class does not.
<FromGitter> <Blacksmoke16> `abstract def name : String` on the `abstract class Animal` type
<FromGitter> <Blacksmoke16> will ensure the children have that method, and compiler would know
<FromGitter> <tvw> Thanks, I will give this a try.
<FromGitter> <Blacksmoke16> if you run into issues making a https://play.crystal-lang.org/#/cr link would be helpful
<FromGitter> <tvw> `abstract def name : String` on the `abstract class Animal` type forces me to implement this method even for subclasses where the method does not make any sense. I do not need a method "fly" for cats.
<FromGitter> <Blacksmoke16> use a module for that, like `include Flyable` which defines a `abstract def fly` method
<FromGitter> <Blacksmoke16> or use another abstract class, only stuff on the parent `Animal` type should be common to all animals
<FromGitter> <tvw> So in order to have a class Bird I also need a module BehavesLikeABird? But I do not see the point where the difference between ⏎ ⏎ class Bird < Animal ⏎ def fly ⏎ end ... [https://gitter.im/crystal-lang/crystal?at=5f2afaa0a2fddd66442648cd]
<FromGitter> <Blacksmoke16> what if you have an animal that is not a bird but can fly
<FromGitter> <Blacksmoke16> like https://en.wikipedia.org/wiki/Flying_fish
<FromGitter> <tvw> I do not. I have only five animals I know everything about. (I only use animals as an example. My class real hierarchy is very limited: 1 base class and 5 subclasses)
<FromGitter> <Blacksmoke16> oh then prob not a big deal no matter how you do it tbh
<FromGitter> <Blacksmoke16> only benefit the module would give you is you could do stuff like
<FromGitter> <Blacksmoke16> ```if animal.is_a? Flyable ⏎ animal.fly ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5f2afc00a541217404e0cead]
<FromGitter> <Blacksmoke16> as compiler would know types that include that module have that method
<FromGitter> <Blacksmoke16> if you can make a playground link with a more specific example/issue that would be easier
<FromGitter> <tvw> if animal.is_a? Bird` would do the job for me - and it surprisingly does. I did not expect, that the if condition would affect on how the compiler understands the animal variable in the if block. That was all what I needed. The Animal class must not be abstract in order to make my code work.
<FromGitter> <Blacksmoke16> if you're never instantiating a generic animal whats the reasoning on why it shouldnt be?
<FromGitter> <tvw> You got me wrong: it makes sense to declare Animal as abstract. But this was not a mandatory part for the solution of my problem from the point of view of the compiler.
<FromGitter> <Blacksmoke16> ah gotcha, see https://crystal-lang.org/reference/syntax_and_semantics/virtual_and_abstract_types.html. It can have an effect
<FromGitter> <tvw> Thanks for `if var.is_a?(...)` - I would not have come to the idea by myself to search for this in the documentation.
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <wyhaines> Anyone know if the Chicago Crystal meetup is virtual or in person?
woodruffw has joined #crystal-lang
<FromGitter> <j8r> it is both, usually
<FromGitter> <RespiteSage> There's still an in-person component now?
woodruffw has quit [Ping timeout: 240 seconds]
<FromGitter> <j8r> there is not `IO#read_char`?
<FromGitter> <Blacksmoke16> could do `read_byte.chr`?
<FromGitter> <j8r> no, it just reads only one byte
<FromGitter> <Blacksmoke16> true
<FromGitter> <j8r> or `read_utf8_char`
<FromGitter> <j8r> I don't use it for now because it is not frequent to only read/write a single char, but may be useful in some cases
<FromGitter> <j8r> also, no `Char#to_slice`...
<oprypin> j8r, wait what
<oprypin> j8r, char.to_s.to_unsafe would do it
<FromGitter> <j8r> it creates a string, so no point to use a char then
<FromGitter> <j8r> (that's what I currently use)
<oprypin> string and slice is the same thing
<FromGitter> <j8r> right
<FromGitter> <j8r> the only way I see then is to yield each byte which make a char
<FromGitter> <j8r> then writing it to the IO
<FromGitter> <j8r> Not worth it anyway 😅
<oprypin> i'm looking to scan through a string with 3 different regexes , which would be equivalent to scan (/regex1|regex2|regex3/), except i dont want to clump their match groups
<FromGitter> <j8r> Finally I use a NUL byte as a string delimiter
<FromGitter> <j8r> oprypin they are complex regexes?
<oprypin> somewhat
<FromGitter> <j8r> you want to have separate match groups for each one, right?
<FromGitter> <j8r> scan 3 times?
<oprypin> now that's not equivalent
<FromGitter> <j8r> it can be worth to create a custom parser, can't tell
<oprypin> well in my case it's not but it's an interesting problem
zorp has quit [Ping timeout: 265 seconds]
<FromGitter> <wyhaines> @RespiteSage It looks that way from the announcement, which is why I was wondering: https://www.meetup.com/Crystal-Lang-Chicago/events/dfpqmrybclbjb/?rv=md2&_xtd=gatlbWFpbF9jbGlja9oAJDkzMjM1NDAxLWRmMTUtNDAzZi1iOWIwLTk3NDQzZDUyNTk2Zg
deimos_ has joined #crystal-lang
zorp has joined #crystal-lang
zorp_ has joined #crystal-lang
zorp has quit [Ping timeout: 260 seconds]
alexherbo24 has quit [Ping timeout: 246 seconds]
Human_G33k has quit [Ping timeout: 256 seconds]
coderobe has quit [Quit: Ping timeout (120 seconds)]
coderobe has joined #crystal-lang
Human_G33k has joined #crystal-lang
uni has quit [Ping timeout: 265 seconds]
woodruffw has joined #crystal-lang
Human_G33k has quit [Ping timeout: 240 seconds]