ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <watzon> Anyone know of a good way to handle JSON deserialization in Ruby?
<FromGitter> <Blacksmoke16> `person = JSON.parse(json_string, object_class: OpenStruct)`
<FromGitter> <Blacksmoke16> might do the trick?
<FromGitter> <watzon> Nah not quite what I'm looking for. I'd like to handle JSON deserialzation in a similar way to Crystal, where you define types, converters, etc for JSON keys.
<FromGitter> <Blacksmoke16> use crystal? :p
<FromGitter> <watzon> Unfortunately Ruby is without annotations, so it definitely wouldn't be as clean as with Crystal
<FromGitter> <Blacksmoke16> why use ruby in the first place then?
<FromGitter> <watzon> Trying to do a project that will actually seem relevant to potential employers
<FromGitter> <watzon> Unfortunately Crystal doesn't do much for a resume
<FromGitter> <Blacksmoke16> do they actually care what lang? i usually just see like `relevant experience with a OOP language`
<FromGitter> <watzon> In my experience they do, at least when you're aiming for senior level positions
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> not related to that pokemon project i take it then?
<FromGitter> <watzon> Yeah no haha. That one's in Crystal.
<FromGitter> <Blacksmoke16> Nice. How's the serializer working out?
<FromGitter> <watzon> It's working great
<FromGitter> <Blacksmoke16> Find any bugs or anything?
<FromGitter> <watzon> Not yet. I haven't really worked on the project since the other day.
<FromGitter> <Blacksmoke16> 👍 ah gotcha
<FromGitter> <Blacksmoke16> So far so good then ha
<FromGitter> <stellarpower> @watzon do you mean like a JSON schema?
<FromGitter> <stellarpower> I used a package in python called that
<FromGitter> <watzon> Kind of. Deserializing JSON objects would require some kind of schema.
<FromGitter> <stellarpower> What I saw was you can import data to ruby and then validate a hash against a class-like structure as a schema. Thus it's agnostic of the data source(I was using yaml)
<FromGitter> <stellarpower> Are you reading from a stream?
<FromGitter> <watzon> Nah just from a HTTP response body
<FromGitter> <watzon> The problem is I have a lot of nested objects
<FromGitter> <watzon> And the JSON needs to deserialize ObjectA which contains ObjectB which contains ObjectC.
renich has quit [Ping timeout: 256 seconds]
<FromGitter> <mattrberry> Is there a way to override the getter defined by the property macro?
<FromGitter> <Blacksmoke16> Use setter and define the getter manually
<FromGitter> <mattrberry> I have this macro (https://github.com/mattrberry/CryBoy/blob/master/src/cryboy/cpu.cr#L11-L28) used a few times here (https://github.com/mattrberry/CryBoy/blob/master/src/cryboy/cpu.cr#L48-L51), where only one of those cases is a special case. Specifically, when getting self.f, I'd like it to drop the bottom 4 bits. I'm guessing there's not a particularly clean approach to that though.. I imagine I'll just
<FromGitter> ... take a different approach
<FromGitter> <Blacksmoke16> Do something to the macro code to conditionally define a unique getter for the special case
<FromGitter> <mattrberry> That was my first thought, and I have a working approach with ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ but I don't necessarily want to have to apply the bitshift on every single call to a register [https://gitter.im/crystal-lang/crystal?at=5ec891e1f0b8a2053aa9f401]
<FromGitter> <Blacksmoke16> Hmm
<FromGitter> <Blacksmoke16> How do you mean?
<FromGitter> <mattrberry> Like it'd be nice to be able to do something like:
<FromGitter> <Blacksmoke16> So why not just do that
<FromGitter> <Blacksmoke16> `macro register(upper, lower, mask = nil)`
<FromGitter> <mattrberry> I didn't realize that was a valid syntax :shrug:
<FromGitter> <mattrberry> Thanks!
rocx has quit [Ping timeout: 260 seconds]
<FromGitter> <sam0x17> yeah on that note, so ok apparently you can have default values in macro parameters? what else can you do? I'm assuming you can't directly specify types or anything (other than raising if it's the wrong type)
<FromGitter> <Afront> are there other "paper books" on Crystal aside from *Programming Crystal*?
alexherbo2 has joined #crystal-lang
<FromGitter> <galvertez> i'm curious about the `@[AlwaysInline]` annotation. gitbook says it gives a "hint" to the compiler. is that to say that the compiler will default to attempting to inline methods, or does it mean more like "try to inline this, but if not, no biggie"
<FromGitter> <galvertez> that is, will the compiler tend toward inlining things, or *not* inlining, except where told otherwise
DTZUZO_ has quit [Ping timeout: 240 seconds]
DTZUZO_ has joined #crystal-lang
DTZUZO_ has quit [Quit: WeeChat 2.6]
_ht has joined #crystal-lang
<raz> i don't know what the annotation does but would say the docs are in conflict there
<raz> ah, just read up, actually they are not
<raz> but i think the wording could be improved, e.g. "Tells the compiler to always inline" (since the word "hint" is misleading)
<raz> since it's called "AlwaysInline" assume that's what it does (otherwise it should be called "PreferInline")
<raz> i assume*
<FromGitter> <galvertez> so the compiler does not default to inlining where possible, yeah?
<FromGitter> <galvertez> i am wondering if private defs could be safely inlined by default
<FromGitter> <galvertez> i mean it's trivial to just type the annotation where i think it belongs, was just thinking about it
<raz> pretty surely it defaults to inlining where reasonable (based on optimization heuristics). if it would inline everything that's _possible_ (which is nearly everything) it would be a rather inefficient ;)
<raz> (lots of duplication, cache pressure etc.)
yxhuvud has quit [Remote host closed the connection]
<jhass> yeah, don't use the annotation unless your profiled your code and then on the call that you assume to be a bottle neck, tried it and profiled again
<jhass> Crystal by itself inlines any block receiving methods, the rest is left to LLVM
<jhass> so the annotation just sets an attribute in the LLVM IR. Weirdly enough I cannot find proper docs for it, best I could find is https://clang.llvm.org/docs/AttributeReference.html but even there it's just referenced in the docs for other attributes
zorp_ has quit [Ping timeout: 246 seconds]
<raz> hrmpf. nested NamedTuples are my nemesis
<raz> is there a simple way to make that work, or do i need a macro, or should i convert to hash? :/
<oprypin> convert to struct
<raz> hummm
<raz> like the whole method argument (no longer take generic namedtuple)?
<raz> or on-the-fly inside the method somehow
<oprypin> raz, define all valid options as structs and accept them
<oprypin> sample https://carc.in/#/r/94ks
<raz> hmm, gonna experiment with that, thx!
<oprypin> namedtuples should be used when they *must* be used, this doesnt appear to be such a situation
<Andriamanitra> can you explain what you mean by that? namedtuples are as good as tuples and tuples are like, super nice i think
rocx has joined #crystal-lang
<jhass> oprypin has the habit of stating his opinion as a fact ;)
<oprypin> asterite's opinion too. close enough to fact
<jhass> asterite's opinion of things isn't the most stable thing :D
<raz> well, i think many people (incl. myself) often want to use them in situations where their limitations don't make them a good fit.
<raz> like the above method arg example is probably a common wall people bump into because that's just such a common thing in ruby, js and other languages
<raz> i think it's mostly the syntax that misleads (they kinda look like hashes, but don't behave like them at all)
<raz> having an extra `MyStruct.new` in there isn't terrible, but it does add a bit of awkwardness. also in other situations (like passing **kwargs around) it gets more complicated.
<raz> (i don't have good improvement-suggestions for these things, they're just observations from what i bump into quite regularly :))
<oprypin> raz, dont foget u can do MyStruct.new(**kwargs)
<oprypin> like, add on overload that does just that and passes it to the normal one
<raz> oprypin: i know and i have. i also convert them to hashes sometimes, merge them (NamedTuple.new(**self, **other)) or get into a divorcement argument with nested macros.
<raz> there are just some situations you don't *want* to put a struct-jacket on them. like when you want to allow the user to pass an arbitrary **kwargs onwards to a method he wrote himself (but still inspect it along the way)
<raz> it's complicated, programming is hard :(
<oprypin> raz, yea those latter are the situations for namedtuple
<oprypin> though not so sure about inspecting them
<raz> well, one day i'll find a good, short example to put on carc.in. in practice i unfortunately always run into it when already 3 levels down the rabbit hole and difficult to extract a meaningful example that fits in a pastie
<raz> like atm i'm extending the jennifer mapping()-macro with some more stuff. it kinda works (except when it gets nested, like in my above simplified example)
<raz> i'm starting to think it should maybe have gone your way instead, and used structs... </thinking-face-emoji>
alexherbo29 has joined #crystal-lang
yxhuvud has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo29 is now known as alexherbo2
HumanGeek has joined #crystal-lang
Human_G33k has quit [Ping timeout: 265 seconds]
travis-ci has joined #crystal-lang
travis-ci has left #crystal-lang [#crystal-lang]
<travis-ci> crystal-lang/crystal#b3ebb1c (master - Allow annotations and ditto in macro (#9341)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/690376428
<DeBot> https://github.com/crystal-lang/crystal/pull/9341 (Allow annotations and ditto in macro)
<FromGitter> <j8r> Struct are also a lot more flexible
<FromGitter> <j8r> Complex namedtuples have also verbose typing :/
<FromGitter> <j8r> How overloads is done undertheground? Is it simples if/elsif in LLVM IR? I can just see by myself
<FromGitter> <j8r> So much code on the `.ll`, I don't know where to look at
<FromGitter> <naqvis> does there exists a crystal bindings shard for cross-platform webview (https://github.com/zserge/webview) library?
<FromGitter> <naqvis> webview is much more cleaner and light-weight than .... (don't want to write electron) lol
<FromGitter> <watzon> I started working on one, then realized that webview is written in C++. So a library would require first writing a C wrapper, then wrapping that wrapper with Crystal.
<FromGitter> <naqvis> aahh
<FromGitter> <naqvis> double work it is
<FromGitter> <watzon> Yeah lol. If only they'd written it in C.
<FromGitter> <watzon> Though webview is pretty small itself I believe. Someone could attempt to write something in pure Crystal.
<FromGitter> <naqvis> but looking at the header file, seems API is in C
<FromGitter> <naqvis> though its interface with GTK, Cocoa etc are done via classes
<FromGitter> <naqvis> i might be wrong ⏎ ⏎ ```#ifdef __cplusplus ⏎ extern "C" { ⏎ #endif``` ⏎ ⏎ but doesn't this mean that ask the compiler/linker to don't mingle exported funcs? [https://gitter.im/crystal-lang/crystal?at=5ec95d042280c80cbfc36f1e]
<FromGitter> <naqvis> also quick `nm` on generated shared library on macos shows ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec95d442280c80cbfc36fbe]
<oprypin> naqvis, yea that looks like a proper and easy C api
<oprypin> it can be internally in c++, that doesnt matter.
<FromGitter> <naqvis> yeah, that's what i understood from glimpsing through the `webview.h` file
<FromGitter> <naqvis> thanks oprypin
<oprypin> almost too easy, huh
<oprypin> it'd probably work even on Windows
<FromGitter> <watzon> Ahh interesting
<FromGitter> <naqvis> i just did a quick and easy try, but .... ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec95e934412600ccd627104]
<FromGitter> <naqvis> 😆
<FromGitter> <naqvis> this is how I build the dylib ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec95f52225dc25f549f4bb4]
<oprypin> naqvis, but thats very easy, you just didnt link it or didnt add to library path
<oprypin> where *is* libwebview.dylib?
<FromGitter> <naqvis> contents of webview.cc ⏎ ⏎ ```#define WEBVIEW_IMPLEMENTATION ⏎ #include "webview.h"``` [https://gitter.im/crystal-lang/crystal?at=5ec95f692c49c45f5a9988db]
<oprypin> nono i dont care
<FromGitter> <naqvis> aahh
<FromGitter> <naqvis> i put that inside the custom folder
<oprypin> what do you mean "the" custom folder :o
<oprypin> LD_LIBRARY_PATH=/the/custom/folder ./crystal-run-webview.tmp
<FromGitter> <naqvis> let me try that
<FromGitter> <naqvis> `LD_LIBRARY_PATH=./ext crystal src/webview.cr` yielding same error though
<oprypin> naqvis, has to be full path tho
<oprypin> to remove confusion which stage has the failure, just do the building and running separately
<oprypin> `LIBRARY_PATH=$(pwd)/ext crystal build src/webview.cr` `&&` `LD_LIBRARY_PATH=$(pwd)/ext ./webview`
<oprypin> (there is no typo or placeholder there, don't change anything)
<FromGitter> <naqvis> still image not found
<oprypin> i dont believe :D
<FromGitter> <naqvis> lol
<oprypin> show me a screenshot of the command line and also include the content of `ls ext`
<FromGitter> <naqvis> ``` $ ls ext/ ⏎ libwebview.dylib``` [https://gitter.im/crystal-lang/crystal?at=5ec96137b101510b20119a6d]
<oprypin> alrighty
<oprypin> it could be misleading, like **a dependency of** libwebview.dylib is missing but it's not saying that
<oprypin> or maybe this *.dylib file is not actually a dylib but an object file? lol
<oprypin> are you 100% confident in those instructions
<oprypin> to build the dylib
<FromGitter> <naqvis> i shared above the instructions i used lol
<FromGitter> <naqvis> ```code paste, see link```
<oprypin> yes that's what i'm doubting now
<oprypin> no seems fine
<oprypin> i dont know this, Mac things.
<oprypin> usually i have a round of debugging on Linux, where this would be eliminated, before getting to Mac
<FromGitter> <naqvis> sure thing
<FromGitter> <naqvis> i was just doing a quick try
<FromGitter> <naqvis> will try to do that on linux to see if encounters the same issue
<oprypin> `otool -L ./webview; otool -L ext/libwebview.dylib` might shine some light
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec9635ef0b8a2053aabb678]
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec96373b101510b20119e49]
<oprypin> no idea , everything seems right
<FromGitter> <naqvis> thanks oprypin
<FromGitter> <naqvis> copying shared lib to `/usr/local/lib` works :)
<FromGitter> <naqvis> no clue on why `LD_LIBRARY_PATH` is not working
<oprypin> aaaaaaaaaaa mac
<FromGitter> <naqvis> rofl
<oprypin> i was getting that symptom before, like, `LD_LIBRARY_PATH=* crystal run` would not work but running the binary directly would work
<oprypin> (and usr/local/lib also fixed it)
<oprypin> but for it to not work when directly specified???
<FromGitter> <naqvis> ```code paste, see link```
<FromGitter> <naqvis> might be the reason
<oprypin> yes it is the reason for what i was saying, but not for what you're seeing
<oprypin> or at least not in the way that i've predicted
<oprypin> could of course be due to the webview thing forking itself
<FromGitter> <naqvis> no clue
<FromGitter> <naqvis> but at least this copying to `/usr/local/lib` working, though not happy path , but at least will give me chance to proceed with writing binding
<FromGitter> <naqvis> thanks oprypin
<oprypin> finally found my (not-so-)old message https://gitter.im/crystal-lang/crystal?at=5ebb23e1faa128031cca3718
<oprypin> and np
<FromGitter> <naqvis> thanks again, so as you suggested `LD_LIBRARY_PATH=foo bash -c '......'` should work
<oprypin> haha no :)
<oprypin> sorry for confusion
<oprypin> that example is purely for demonstrating that the variable penetrates only exactly one process. bash is being used only as an environment-variable-printer there
<oprypin> other than that it can only make things worse
<oprypin> one day some knowledgeable person will come and say "oh you should just use @rpath" or "oh you should just use @executable_path" but i have no idea. and not having access to a mac doesnt help xD
<oprypin> could be the way that the dylib is build. i should try running otool on mine
<FromGitter> <naqvis> interesting
<FromGitter> <naqvis> might be the way dylib is build
<oprypin> naqvis, i think you have another very interesting option. building the webviewbinding as an object file rather than a dynamic library, and then linking it directly into your application
<oprypin> probably will work better
<FromGitter> <naqvis> yeah, but that will require linking against `WebKit` framework at time of compiling crystal source code
<oprypin> naqvis, uhhhh yes that is correct
<oprypin> doesnt it require that anyway
<FromGitter> <naqvis> also i was just doing `man dyld` and it is written on the very first page ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec96d4a225dc25f549f6c62]
<FromGitter> <naqvis> that's the main reason, setting LD or DYLD doesn't work
<FromGitter> <naqvis> because OSX just ignore that
<oprypin> i just sent a link where it works though :o
<FromGitter> <naqvis> os x box you have SIP enabled?
<oprypin> indeed it differs in that it has everything starting with @rpath
<FromGitter> <naqvis> CI VM i doubt will enable SIP
<oprypin> naqvis, oh it does
<oprypin> thats why i've been having all those complaints
<oprypin> travis ci doesnt have it enabled though
<FromGitter> <naqvis> osx Catalina?
<FromGitter> <naqvis> yes it is
<FromGitter> <naqvis> same version as mine
<FromGitter> <naqvis> 1) 15.3
<FromGitter> <naqvis> 1) 15.4*
<oprypin> naqvis, so the difference is that my dyld has an @rpath and yours doesnt. but even in my case it barely works (e.g. cant do `LD_LIBRARY_PATH=foo crystal run` as that's 2 processes deep) so it's hardly a solution
<oprypin> i didnt do this @rpath thing myself, it's CMake's default
<FromGitter> <naqvis> then I guess simple solution would be to avoid generating custom dylib
<FromGitter> <naqvis> just link against obj file and then have final version link against system libs :)
<oprypin> yes
<FromGitter> <naqvis> and why in `@[Link(ldflags:` relative paths doesn't work?
<FromGitter> <naqvis> i mean for custom build objs or libs, stored in custom locations, why it require to provide the full path?
<FromGitter> <naqvis> can't we just use relative paths?
<oprypin> naqvis, i think the main problem is relative to *what*
<oprypin> in crystal's case, relative to $cache/.crystal/mangled-main-name.cr/
<oprypin> thats why you specify relative to current file, using __DIR__
<oprypin> naqvis, the important part is, the full path to obj will not be permanently stored, the obj will just be absorbed entirely
<oprypin> naqvis, for examples see https://github.com/oprypin/crsfml/search?q=ext
zorp_ has joined #crystal-lang
<FromGitter> <naqvis> agree, but my point was that compiler does know where the file reside and definitely path is relative to that, so compiler could have taken care of that no matter where it compiles that code
<FromGitter> <naqvis> DIR is an option, but no the clean one imo
<FromGitter> <naqvis> or might be that compiler think, ppl will be just linking against system libs, so there won't ever be use-case of custom build objects
hightower2 has quit [Ping timeout: 265 seconds]
<FromGitter> <naqvis> hurray lol
<oprypin> :>
<oprypin> straight-shoota, hold on.... i can't believe, it seems like crystal has no equivalent of `$(cd "$x" && pwd)`
<oprypin> other than, of course, doing exactly that
<oprypin> Python has `Path("a") / Path("/b") == Path("/b")`
<oprypin> Crystal has `Path["a"] / Path["/b"] == Path["a/b"]`
<straight-shoota> => Path["/b"].expand(Path["a"])
<oprypin> oooooh
<oprypin> thank you
<straight-shoota> I find Pythons behaviour weird that joining two paths results in the second path
_ht has quit [Quit: _ht]
<oprypin> straight-shoota, no it's not weird at all, it's the `cd` behavior
<oprypin> when you're in "a", of course `cd b` and `cd /b` should be different
<oprypin> it's crystal's behavior that's really weird
<straight-shoota> yes, but cd isn't join
<oprypin> yes but `/` isn't join
<straight-shoota> cd resolves a path relative to the current directory
<straight-shoota> in Crystal, that's Path#expand
<oprypin> btw the full code is `(Path["/b"].expand(Path["a"], expand_base: false))`
<straight-shoota> The equivalent to `Path["a"] / Path["/b"]` in shell would be like `a="a";b="/b";"$a/$b"` => `a//b`
<oprypin> uhh
<oprypin> i get it that `cd` could put you under a symlink and it's not the same, but it's whatever
<oprypin> yea python is weird too tbh
<oprypin> no but like.. how can you silently ignore the leading slash, it just has an entirely different meaning
<oprypin> anyhow, Crystal.normalize_path is really weird
<oprypin> changing it to https://github.com/crystal-lang/crystal/blob/ed26aa796c0c51bc75a05eee5290d804f860add1/src/compiler/crystal/util.cr#L64 which further exposes the weirdness but also kinda shows that `absolute?` by itself might not be enough generally
<oprypin> which i have no idea if it's actually worth preserving
<oprypin> another interesting thing is `./foo` has special meaning on both linux and windows, and most transformations drop it
<oprypin> though to be fair that meaning is specific to shell and powershell respectively
companion_cube has joined #crystal-lang
<oprypin> as an even more rambly thought, i'm guessing that powershell supports backslashes in paths even on Linux
hightower3 has joined #crystal-lang
<oprypin> haha it does
FromGitter has quit [Remote host closed the connection]
oprypin has quit [Quit: No Ping reply in 210 seconds.]
oprypin has joined #crystal-lang
FromGitter has joined #crystal-lang
<yxhuvud> shell also does stuff like expanding ~ etc. The question is how much of that behaviour that should leak into the language
<companion_cube> https://play.crystal-lang.org/#/r/94pj is this expected? seems a bit like a bug to me
<raz> looks expected to me
<hightower3> Yes the ~ should be shell-only. If one needs to expand homedir inside a language there's always HOME env var
<companion_cube> raz: really? to me `//` and `/` are more or less the same
<companion_cube> I don't know the URI spec, but on unix paths it'd definitely be a bug
Stephie has quit [Ping timeout: 256 seconds]
Vexatos has quit [Ping timeout: 256 seconds]
<companion_cube> but it doesn't speak of // inside the path, only at the beginning? I must be missing something
FromGitter has quit [Remote host closed the connection]
<raz> path segments are allowed to be empty
<raz> that's different from POSIX where consecutive slashes must be collapsed into one
FromGitter has joined #crystal-lang
<companion_cube> interesting, ok. TIL.
oprypin has quit [Quit: No Ping reply in 180 seconds.]
Stephie has joined #crystal-lang
oprypin has joined #crystal-lang
<companion_cube> thanks for the answers :)
Vexatos has joined #crystal-lang
<raz> np, i only know cause i had to look this up myself ages ago. wikipedia has a more readable description: https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Generic_syntax
<lunarkitty> Does play.crystal-lang.org run in browser or server side? Does crystal support wasm now??
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<hightower3> lunarkitty, for 1) it runs on server, and displays result. the result is also cached for subsequent visits to the same paste
<hightower3> for 2) not sure but I think no wasm (yet?)
<FromGitter> <Blacksmoke16> hey raz, you around?
<raz> si, but about to crash
<FromGitter> <Blacksmoke16> ah no worries, can wait till tomorrow
sz0 has quit [Quit: Connection closed for inactivity]
<companion_cube> hmm, http::client doesn't seem to follow redirects at all