<Papierkorb>
There's no list of active signals in an obejct though
<Papierkorb>
I decided against doing at on all objects as I wanted that stuff to be used on tons of objects, and not only on a select few due to memory bloat
<Papierkorb>
You can of course collect all signals of an object, e.g. in #initialize
<hightower3>
Right, ok will do that
<Papierkorb>
And then later just do a `@signals.each(&.disconnect)`
<FromGitter>
<faustinoaq> @Qwerp-Derp Maybe you can create your own extension for archive this feature. I think your idea is kinda useful for other languages too, like Python, Ruby, Bash, etc, etc. see: https://code.visualstudio.com/docs/extensions/overview
<hightower3>
Collecting signals in initialize is a bit inconvenient though, because I both have to do Cute.signal in the class, and @signals = [ @cute_signal_<name>...] in initialize, which means I need to define initialize() in all classes
<FromGitter>
<codenoid> same problem @kazzkiq
<FromGitter>
<codenoid> when i got arabic language
<Papierkorb>
hightower3: Don't access the @var directly, use the getter. They're lazy-initialized.
<hightower3>
ok
<Papierkorb>
Are the signatures the same?
<Papierkorb>
well, even if not. I'd probably write a small macro for that *cough*
<hightower3>
Papierkorb, I've added a quick @name = :{{ call.name.id }} in macro signal, but I just realized that the idea of emitting "new_listener.emit @name" inside on() won't work. And it won't work because self in on() is the signal, not the parent object. So no one is attached to that signal (those who wanted to attach did so on parent.new_listener.on() { block }, not on parent.cute_signal_<name>.on...). Right?
<Papierkorb>
`self` in the #on block is the same as outside, it's not changed.
<Papierkorb>
I'd simply write a wrapper #on-esque method taking a Signal, passing the given block, and also call to the new_listener stuff from there
<Papierkorb>
You can pass its name on, or just the Signal itself. Both will work.
<hightower3>
"taking a Signal", you mean I would pass @cute_signal_<name> there?
<Papierkorb>
sure
<Papierkorb>
Cute::Signal is a normal class as far the compiler is concerned
<hightower3>
Right, this could probably work. (I currently have this: https://play.crystal-lang.org/#/r/2id1 , but the new_listener isn't triggering, not sure why then. I could be tired and not seeing the obvious)
<Papierkorb>
well your"on" method lies in your EventMitter module, but it's never used by the Signal. each Signal sub-class has a #on implementation, which is specific to that sub-class (based on the signal signature)
<Papierkorb>
even if you wanted, you can't really "override" it
<hightower3>
yeah, that is what I was referring to with the comment about self
<hightower3>
(didn't mean to say that 'self' is somehow temporarily changed, but that it's called on the wrong object)
<hightower3>
(it's called on the signal, instead of on its "parent")
<hightower3>
Papierkorb, I probably do need on()-esque wrapper method as you said. Ok, I believe that about wraps up all the investigation I had to do before embarking on the task. Thank you for the discussion.
<hightower3>
no particular luck with making it work, though...
<hightower3>
Papierkorb, the problem seems to be that I need to call obj.my_on ( signal, block) , and since I must pass a signal variable and I must reference @cute_signal_*, it also means all signals need to have getters on the object
<Papierkorb>
mh? They have getters?
<hightower3>
Ok, great, then that's a line less to write, but still... I don't like the obj.my_on( obj.cute_signal_*, ...), and also another problem (which may be based on my lack of understanding) is that I can't pass an arbitrary block to my_on (to be passed to the real #on), but I need to prepare in advance all possible types of arguments. Is that right?
<Papierkorb>
the @cute_signal_x stuff is internal, the name is so clunky that it should never ever collide with something you write yourself. The getter is just the `x`.
<hightower3>
oh ok
<Papierkorb>
You .. don't want to prepare all possible types, even if you were to restrict yourself. let the compiler do that for you if possible.
<Papierkorb>
Just using `yield` in the block you pass to #on should just work.
<hightower3>
ooh let me try that
<hightower3>
def my_on( signal) signal.on() { yield } #==> can't use `yield` inside a proc literal or captured block
<Papierkorb>
I still don't know why you want to know when someone connected btw
<Papierkorb>
Knowing if someone is connected is useful - Well, rarely, but I did find a use for that once in 3 years of Qt
<Papierkorb>
But when someone connects? Do you really need that?
<hightower3>
The program runs a method when someone connected and looks which signal it was. Then based on the signal, does something. E.g., if someone connects to anything related to mouse, it enables mouse controls.
<hightower3>
All this can probably be reworked, sure...
<FromGitter>
<bew> It's not exactly the same problem than your but you may find a similar solution I think
cyberarm has joined #crystal-lang
sp4rrow has quit [Quit: The Internet needs a break and I need a cookie]
mark_66 has joined #crystal-lang
mark_66 has quit [Client Quit]
<FromGitter>
<bew> For those who worked or are working on bindings of big libraries like sfml @oprypin (or qt @Papierkorb ?), how did you started? Do you generate the bindings (the Crystal's lib) and the wrappers? Or only the bindings? How do you generate them? Do you have some guidelines on that? Thanks
DTZUZO has quit [Ping timeout: 240 seconds]
rizo[m] has joined #crystal-lang
sp4rrow has joined #crystal-lang
snsei has joined #crystal-lang
sp4rrow has quit [Client Quit]
snsei has quit [Ping timeout: 276 seconds]
<FromGitter>
<konovod> Sfml\Qt are of of course more complex to bind then say lapack, so not sure if i qualify, but for all few libs I did I first generate "raw bindings" using `crystal_lib` (with some tinkering and fixes in process), add some specs to see it works, then write object-oriented wrapper that covers all (or most) functions that raw bindings provide.
<FromGitter>
<bew> Hi @konovod thx! I'd say that this is the basic workflow for most bindings, as you have one or two header files to replicate. But for huge libraries with dozen of headers and hundreds of functions, I'm not sure we can use the same workflow..
<FromGitter>
<andreaTP> it looks like that `begin` `end` without an `ensure` or `rescue` block doesn't catch the exception, is it expected??
<FromGitter>
<bew> it is, what would you want to do in case of an exception if you specify no code to execute when an exception occurs?
<FromGitter>
<konovod> @bew the main problem for c++ libraries are even not a number of functions. @oprypin written\generated own c-style wrapper for sfml, and for a qt i'm afraid to even imagine what could be needed. Working qt bindings would be awesome though.
<FromGitter>
<andreaTP> @bew normally it does mean that I want to ignore that exception
<FromGitter>
<andreaTP> and I rephrase, if a`rescue` block is missing it throws anyway
<FromGitter>
<andreaTP> at least that is the expected behavior for me :-)
<FromGitter>
<bew> @andreaTP weird ^^ is it a behavior from Ruby?
<FromGitter>
<andreaTP> @bew sorry, never coded more that 20 LOC in a row in Ruby in my life :-) I come from a java/scala/C background mostly
<FromGitter>
<andreaTP> maybe that's why it's unsound to me XD
<FromGitter>
<bew> @konovod true, I didn't target C++ huge lib specifically, more C libs, but the workflow should be the same once you have a C wrapper lib for the cpp lib IMO
<Yxhuvud>
andreaTP: What is unsound is wanting to rescue everything under the sun.
<FromGitter>
<andreaTP> the fact that if the 'rescue' block is missing the exception is propagated ...
<FromGitter>
<andreaTP> but nothing bad :-)
mark_66 has joined #crystal-lang
<jokke>
hey
<jokke>
i get the following error: Capture group 'nick' was not matched
<jokke>
when matching a string
<jokke>
why is that?
<jokke>
can't it just be nil?
<jokke>
ah never mind
<jokke>
[]?
hightower2 has joined #crystal-lang
gloscombe has joined #crystal-lang
bmcginty has quit [Ping timeout: 240 seconds]
bmcginty has joined #crystal-lang
snsei has joined #crystal-lang
sz0 has joined #crystal-lang
snsei has quit [Ping timeout: 258 seconds]
<Papierkorb>
bew, I manually write a real small wrapper first (PoC), and then head on to architecturing the API I'd like to see. For small libs, I really just keep on writing the bindings manually. For Qt, I'm writing a Clang wrapper to deal with C++.
<Papierkorb>
Writing bindings isn't much about getting the C bindings right, a good wrapper provides an API to the user which feels natural in the target language. E.g., C++ doesn't have blocks, so neither does Qt, but the bindings will use them where appropriate.
<FromGitter>
<bew> Thanks @Papierkorb! I completely agree with you :) I've started a binding of XCB, but I was going manually to test things out. I (very) recently discovered that I could generate bindings I didn't know what to do about it, now I know that I'm headed in the right direction with my manual PoC, and I'll probably use generation later. Thanks a lot ;)
<alex``>
What is the difference between `crystal init lib` and `crystal init app`?
<Papierkorb>
alex``: the former creates a project to be used as library ("shard"), the latter as stand-alone application
<alex``>
Ouki thanks
<alex``>
Papierkorb: in which way the structure differs?
bmcginty has quit [Ping timeout: 276 seconds]
<Papierkorb>
alex``: barely. the README.md has information how to include the shard for a lib, and the shard.yml has a "target" (= main program source code file) if it's an application
bmcginty has joined #crystal-lang
<alex``>
Thanks :')
<crystal-gh>
[crystal] ysbaddaden opened pull request #4821: Support LLVM 5.0 (master...core-support-llvm-5.0) https://git.io/v7Svn
bmcginty has quit [Ping timeout: 240 seconds]
liosha has joined #crystal-lang
<liosha>
Crystal code supporting LLVM 3.5 says: In LLVM 3.5 we can't write a bitcode to memory
<liosha>
So, removing LLVM 3.5 can improve performance?
<Papierkorb>
if you don't have llvm3.5, it's not being used. The most recent one is
<Papierkorb>
llvm35 is old, but people wanted to keep it around as there were some users on some old RHELs, which only ship with llvm35
alex`` has quit [Quit: WeeChat 1.9]
<liosha>
Ok, :+1: Thanks you <Papierkorb>
liosha has left #crystal-lang [#crystal-lang]
DTZUZO has joined #crystal-lang
bmcginty has quit [Ping timeout: 276 seconds]
bmcginty has joined #crystal-lang
bmcginty has quit [Ping timeout: 246 seconds]
bmcginty has joined #crystal-lang
rizo[m] has quit [*.net *.split]
vegai has quit [*.net *.split]
rizo[m] has joined #crystal-lang
vegai has joined #crystal-lang
bmcginty has quit [Ping timeout: 276 seconds]
bmcginty has joined #crystal-lang
snsei has joined #crystal-lang
snsei has quit [Ping timeout: 240 seconds]
alibby has joined #crystal-lang
alibby1 has quit [Ping timeout: 260 seconds]
alex`` has joined #crystal-lang
<Papierkorb>
@sdogruyol, wrt the confusing option parsing some time ago, I may have something in store to fix that
tzekid has joined #crystal-lang
beardedeagle has joined #crystal-lang
<FromGitter>
<bararchy> So, having issues connecting to local IIS server with HTTP::Client, the certificate is invalid , so I overload the `tls: ` with a new context using verify none. ⏎ using curl on https works, using TTP::Client on non ssl works, using HTTP::Client on ssl with new context fails after a minute or so with the message: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/c
<FromGitter>
<bararchy> Using only SSL connection via: SSL Socket also works, so I guess the issue is somwhere with the HTTP::Client and not the SSL socket it self
snsei has joined #crystal-lang
mark_66 has quit [Remote host closed the connection]
<FromGitter>
<bew> I would expect the lib fun to find the one in binary
<FromGitter>
<bew> @fridgerator You can use a `Slice(Int32)` instead of an array to correctly get the filled values
<FromGitter>
<bew> The issue with the array is that the array gets filled, but the `size` attribute cannot be updated, the array has no way to know that the lib call filled the array with some data, and how many.
Philpax_ has quit [Ping timeout: 276 seconds]
Philpax_ has joined #crystal-lang
<FromGitter>
<fridgerator> that works! thanks @bew
<FromGitter>
<bew> When you were doing `Array(Int32).new(numvars)` (given `numvars = 4`), it'll create an array of initial capacity of 4, but of size 0.
<FromGitter>
<fridgerator> ah ok
<FromGitter>
<fridgerator> makes sense, appreciated!
<FromGitter>
<bew> you're welcome ;)
beardedeagle has quit [Quit: WeeChat 1.9]
d20master has joined #crystal-lang
<d20master>
Anyone have an example of statically cross compiling crystal for use in a moby distro ( alpine linux ) ?
<d20master>
I'm thinking it is exactly the same as just cross compiling crystal statically, but I am not sure.
<FromGitter>
<LuckyChicken91_twitter> im sure its excatly the same
<d20master>
cool
early has quit [Quit: Leaving]
Renich[m] has quit [Read error: Connection reset by peer]
watzon has quit [Remote host closed the connection]
braidn[m] has quit [Remote host closed the connection]
olbat[m] has quit [Read error: Connection reset by peer]
rizo[m] has quit [Read error: Connection reset by peer]
vegai has quit [Read error: Connection reset by peer]
TheGillies has quit [Remote host closed the connection]
jplatte has quit [Read error: Connection reset by peer]
thelonelyghost has quit [Remote host closed the connection]
sija[m] has quit [Read error: Connection reset by peer]
early has joined #crystal-lang
olbat[m] has joined #crystal-lang
dannyAAM_ has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
<FromGitter>
<sdogruyol> @papierkorb sorry, I didn't get what you meant
bmcginty has quit [Quit: Reconnecting]
bmcginty has joined #crystal-lang
TheGillies has joined #crystal-lang
Renich[m] has joined #crystal-lang
braidn[m] has joined #crystal-lang
thelonelyghost has joined #crystal-lang
rizo[m] has joined #crystal-lang
jplatte has joined #crystal-lang
vegai has joined #crystal-lang
watzon has joined #crystal-lang
sija[m] has joined #crystal-lang
dannyAAM has joined #crystal-lang
alex` has joined #crystal-lang
alex` is now known as Guest31091
d20master has quit [Ping timeout: 260 seconds]
sz0 has quit [Quit: Connection closed for inactivity]
hightower3 has joined #crystal-lang
hightower2 has quit [Ping timeout: 240 seconds]
Renich[m] has quit [Ping timeout: 240 seconds]
jplatte has quit [Ping timeout: 240 seconds]
watzon has quit [Ping timeout: 255 seconds]
sija[m] has quit [Read error: Connection reset by peer]
thelonelyghost has quit [Read error: Connection reset by peer]
TheGillies has quit [Read error: Connection reset by peer]
olbat[m] has quit [Read error: Connection reset by peer]
rizo[m] has quit [Read error: Connection reset by peer]
braidn[m] has quit [Read error: Connection reset by peer]
vegai has quit [Read error: Connection reset by peer]
olbat[m] has joined #crystal-lang
<FromGitter>
<bararchy> So , right now crSFML is Crystals most dominant game engine .
<FromGitter>
<bararchy> What about a Godot style GUI for it ?
<FromGitter>
<bararchy> :)
braidn[m] has joined #crystal-lang
watzon has joined #crystal-lang
thelonelyghost has joined #crystal-lang
Renich[m] has joined #crystal-lang
TheGillies has joined #crystal-lang
rizo[m] has joined #crystal-lang
vegai has joined #crystal-lang
jplatte has joined #crystal-lang
sija[m] has joined #crystal-lang
d20master has joined #crystal-lang
<oprypin>
you say dominant as if anyone is actually using it
<oprypin>
there's the stars on github, there's the initial fiddling with it, but i havent seen any big projects come out of it
<oprypin>
might as well do .as(Void*) right away, why mess with object_id
<FromGitter>
<bew> no reason, I thought I already changed it
<FromGitter>
<bew> used `.as(Void*).address` to easily serialize/send it
<FromGitter>
<bew> could do `pointerof` too..
<oprypin>
no
<FromGitter>
<bew> no?
<oprypin>
class is a pointer to data on the heap. you want to get the pointer, not pointer of the pointer
<FromGitter>
<bew> oh right thx
Guest31091 has quit [Ping timeout: 240 seconds]
alex`` has quit [Ping timeout: 255 seconds]
<FromGitter>
<bew> About my syndrome on XY problem: I never ask for solution for a general problem X unless I don't want to think about it...
<FromGitter>
<bew> It's true that it can generate some Y questions sometimes, but it's how I learn exactly how things works. And I don't see another workflow where I wouldn't ask Y questions, and get where I want (learn how sth works) without having to read some code I didn't wrote which would be the easy way but would not be challenging.. (long lines sorry)
<oprypin>
bew, sorry, this is not worth worrying about
<FromGitter>
<bew> yeah I know, just wanted to point it out, in case you'd have an idea how to prevent XY from me :)
<Papierkorb>
Your explanation reminds me of the butterfly effect somehow. Dunno. Could be rewatching Steins;Gate.
<Papierkorb>
Maybe more useful, the issue is not that you're looking for a solution to a problem. XY's usually happen when one wants to force a certain solution without taking a step back (after seeing issues ahead) and looking at the whole picture again
<Papierkorb>
bew, on a different note, I don't see you XY'ing often at all. Wanting to know how to do hacky stuff is fine, as long you know they're hacks and, more often than not, rethink afterwards lul
<FromGitter>
<bew> thanks I think I understand. So I used a hack.. and you're kinda saying that it's probably a bad idea to base a library on this hack? :/ How would I resolve my problem, without using this "hack" to recreate objects using it's address?
<Papierkorb>
The funny thing is, if you know the address, you have the object.
<Papierkorb>
So, storing the object_id is exactly same as storing the object right away
<Papierkorb>
Except that object_id being the objects memory address is a implementation detail, so you shouldn't rely on it as long you can get around it
<oprypin>
Papierkorb, no but object_id is an implementation detail that happens to be .as(Void*).address
<oprypin>
yeah......
<oprypin>
so if you mean the address, use the address, thats what i mean. the xy was clinging to object_id. but it's no big deal coming from you.
<oprypin>
using the address seems fine, but not sure how it might bite you
<Papierkorb>
Using the bare address is fine, except when you forget some detail, crashing the application with a nice (but probably useless) segmentation fault
<FromGitter>
<bew> @oprypin oh I get you on the xy thing about object_id, true it was not what I should've asked, thanks for clarification
<Papierkorb>
bew, One of the things with hacks are that you have no room for error. If you mess up, shit hits the fan. E.g., if you just store the Object itself (Which takes exactly the same memory space as the object_id), the compiler will prevent you from doing stupid things™. A bare address, and later, pointer, won't
<oprypin>
no but i think this is for inter process communication
<FromGitter>
<bew> yeah that I know, yes @oprypin that's it
<oprypin>
obviously there's no need to store the address in normal circumstances
<Papierkorb>
... Do NOT take the address coming from a remote end and just turn it into an object blindly
<Papierkorb>
bew, you can use the object_id as identifier, but as part of a Hash(UInt64, TheObject) of sorts.
<oprypin>
very well put
<FromGitter>
<bew> then, how can I check it's a valid address from one of my objects ? I can't use a hash like this, as there could be a lot (huge number) of objects
<FromGitter>
<bew> is there a way with the GC to check that a given pointer is managed by the GC ?
<oprypin>
bew, that's not solving anything. the pointer could be storing something entirely different later.
<Papierkorb>
bew, you're asking for a security desaster
<FromGitter>
<bew> then it seams to be a risk without solution :/
<Papierkorb>
A Hash is a solution
<Papierkorb>
Memory is cheap. Or, cheaper than someone taking over your computer.
<oprypin>
you definitely should do this hash thing
<Papierkorb>
bew, also, define "a lot"
<oprypin>
you should keep every object that you still consider valid in the hash. if it's no longer valid then you will explicitly fail the RPC call
<Papierkorb>
bew, *cough* Cannon RPC can manage remote resources *cough* And it also uses a Hash of objects. Don't have to tell you that cannon is ought to be lightweight. But not insecure. (Apart from the documented stuff lol)
<oprypin>
Papierkorb, how do you deal with objects that only your lib's Hash keeps track of? doesnt it prevent everything from being GC'd
<FromGitter>
<bew> oh I might have an idea, storing in an array each pointer of object I'm sharing with the other process, and giving it the id (necessary to get the pointer back from the id)
<FromGitter>
<bew> so the client process only knows about ids, not real pointer
<oprypin>
well sure that beats any other solution
<Papierkorb>
oprypin: Of course, that's by design. For non-static services (which probably never get GC'd during the lifetime of the process), clients can get ownership of a remote resource, and as such, must not be silently killed on the host.
<FromGitter>
<bew> yeah I know you have your Cannon project, but that would be "looking at someone else's code :P )
<Papierkorb>
bew, and then you add one object and remove another one. Kaboom. Array's not good enough.
<oprypin>
Papierkorb, mmmm the remote finalizer could tell the hash to forget about the object but that's a bit crazy
<FromGitter>
<bew> no I don't remove them fromo the array
<FromGitter>
<bew> not needed in my case
<oprypin>
i think a Hash with incremental IDs is the best
<oprypin>
better than object_id which is not guaranteed to be unique over time
<FromGitter>
<bew> the number of object is.. the number of ast node, after a success parsing of the crystal source code :)
<Papierkorb>
oprypin: Not really, as the remote entity *is* the owner. A remote entity can only kill objects they own however.
<Papierkorb>
bew, that's highly unlikely as you're not doing remote stuff on a whole AST in parallel.
<Papierkorb>
bew, even if you were building a distributed compiler, you'd not design it like that.
<FromGitter>
<bew> the basic idea I had earlier today, was that I wanted to think about a way to have a `macro run program` that would have access to the current AST, with the same flexibility than current macro system has access to the AST..
<oprypin>
wow
<Papierkorb>
... That would simply pipe the serialized AST through stdin, and receive serialized AST from stdout. No further RPC necessary.
<Papierkorb>
Especially, no network
<oprypin>
well perhaps receive actual source code in stdout but yeah
<FromGitter>
<bew> without having to serialize the whole AST, as I don't need all ASTNode datas
<Papierkorb>
Then send less, or send everything and don't care
<FromGitter>
<bew> only specific nodes, I think it's a bit overkill to send "hey all 99999999 ASTNode datas for you"
<Papierkorb>
It's not like I/O will be a bottleneck using the standard streams. You can shovel gigabytes per second through them.
<oprypin>
bew, how much source code can you have? 1 MB? is that a lot of RAM to share with another process?
<FromGitter>
<bew> yeah but on the client (the code generator) I don't want to store the whole AST, but only what I need..
<Papierkorb>
Not to mention the hugely increased complexity of having to ask for some data, caching logic, etc.
<oprypin>
why do you think ad hoc inter process communication is better than storing at most 1 MB of data?
<Papierkorb>
In theory, there's also shared memory, which is even faster (literally instant, thank you MMU). But nah, standard streams will do perfectly fine
<FromGitter>
<bew> well first I'm not sure how we could serialize the whole AST with all datas collected when a macro runs
<Papierkorb>
The source-code representation sounds fair
<FromGitter>
<bew> yeah I thought about shared memory too, but I can't set it to be read-only without beeing root :/
<Papierkorb>
... you can
<Papierkorb>
But SHM is completely overkill for that
<Papierkorb>
Not to mention that you still have to serialize the data
<oprypin>
or do you 🤔
<Papierkorb>
bew, don't optimize what's not bottle-necking. The problem is, you think it'll be an issue, but I doubt you have empirical data supporting that position. You won't have issues.
<FromGitter>
<bew> source code representation? how would this help? I'd need to reparse, run preliminary visitors to get necessary data for the macro run, then check what I need? that's the compiler work, I want to just ask for data I need
<oprypin>
how do you expect to set up runtime access by string to every method of every ast node i have no idea
<FromGitter>
<bew> that I was thinking about rewriting a part of the MacroInterpreter, to allow access to it from the macro system, but (maybe also, not sure how) from a remote process
<FromGitter>
<bew> or with a layer between the remote and the interpreter, but not too much, to prevent having to duplicate effort when adding macro methods and stuff
<FromGitter>
<bew> @oprypin not all astnode methods, only thoses exposed by the MacroInterpreter
<Papierkorb>
How many can there be in a common macro? A few thousand?
<FromGitter>
<bew> sorry don't understand your question..
<FromGitter>
<bew> curently: 309 methods
<FromGitter>
<bew> (count of 'def' in compiler/crystal/macros.cr)
d20master has quit [Ping timeout: 260 seconds]
<oprypin>
that's the documented stubs, anyway
<FromGitter>
<bew> (if your question was about the number of current methods the interpreter handles, sorry if it wasn't it)
<FromGitter>
<bew> yeah but that's about the number of methods the interpreter handles right?