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 [Ping timeout: 256 seconds]
deavmi has joined #crystal-lang
zorp has quit [Ping timeout: 260 seconds]
rocx has joined #crystal-lang
livcd has quit [Ping timeout: 264 seconds]
_whitelogger has joined #crystal-lang
<FromGitter> <cbortz> Hey y'all! I have a question about the shards.yml file in projects. What exactly is the `:crystal` property used for? My assumption was that it would somehow require that version of crystal, but the amber project has the value set to 0.33.0 when the version 0.34.0 is actually used. Also, I could install the shards just fine on my machine even though I don't have version 0.33.0 installed. Can someone explain what
<FromGitter> ... this property is actually used for?
alexherbo2 has joined #crystal-lang
<FromGitter> <naqvis> afaik that shows the version of crystal which was used to develop
<FromGitter> <naqvis> like when you create new app/lib via crystal cli it will use current crystal version for that property
<FromGitter> <cbortz> So almost as if the intent is to be informative rather than prescriptive? Am I understanding that correctly?
_whitelogger has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #crystal-lang
<oprypin> @cbortz: you say "known to work with this Crystal version". it is not used.
alexherbo2 has quit [Ping timeout: 258 seconds]
<oprypin> there is also an extlibs field that is not used
<oprypin> oh woops that's "libraries", not "extlibs"
<raz> speaking of shard.yml, it would be nice if the 'version' could be fetched programmatically so i don't have to maintain it in two places (shard.yml & version.cr)
<raz> (or the other way round like in ruby, where you can just reference code-consts in the .gemspec, but not sure if that's feasible)
<oprypin> yea wouldn't it
<oprypin> which one will it be, requiring compilation of Crystal code to get the version for shards *or* requiring libyaml to get the version for runtime
<raz> i'd say requiring libyaml but only in the compiler, so it can parse at a compile time and embed the version string :)
<raz> otoh, i don't even need the shard version in app-code very often. it's just there by default (create by `crystal init`), so feels like it wants to be maintained
<oprypin> yea
<jhass> I mean you could just regex it out
<jhass> or probably even have little handparser to avoid libpcre
alexherbo2 has joined #crystal-lang
<raz> yup, it should be fairly easy. just feel like that should/could be something in crystal itself. otherwise everyone has to think about it / solve it in a different way
<raz> `VERSION = SemanticVersion.parse(YAML.parse(File.read("./shard.yml"))["version"].to_s)`
<raz> basically a macro like that somewhere
* raz scratches head
<raz> (in fact, perhaps version.cr could just be auto-generated with such a macro instead of a fixed string?)
<raz> ah, well, that would being the yaml dep into every project tho, i suppose
* raz needs more coffee
<oprypin> no no no that exact thing was already proposed and thankfully shot down
<oprypin> the only way to do this is to enforce version.cr being "trivial" with a tiny subset of Crystal parser
<FromGitter> <galvertez> well kind of my point was that `OpenSSL::SSL::Server` isn't actually anywhere in docs or in code, but i have used it as a socket before, so i am pretty sure it's not an ssl context
<FromGitter> <galvertez> that is, i did not even realize until checking docs that it should be `OpenSSL::SSL::Socket::Server` rather than `OpenSSL::SSL::Server` - i just guessed, and it worked, so i didn't read much into it lol
<FromGitter> <galvertez> but i got even more confused when i tried the same thing w/ the client socket, and that didn't work.
<FromGitter> <galvertez> i am actually hugely surprised that `OpenSSL::SSL::Server` doesn't throw a compile errorr. i seriously can't find that constant anywhere
<FromGitter> <galvertez> it's less surprising that `OpenSSL::SSL::Client` does throw an error :)
_ht has joined #crystal-lang
<jhass> gallvertez: see my link above?!
<jhass> gosh, the threading really messes up the bridge :/
<jhass> oprypin: maybe would be worth to include a link to the thread for thread replies or something
<jhass> or maybe even a thread ID and allowing to reply to it with a prefix
<FromGitter> <naqvis> not only bridge but also cellphone app
<oprypin> lol i can guess without looking that the api doesn't expose threads
<FromGitter> <naqvis> they recently added threading feature so they might have added the api
<jhass> maybe they put someting into meta? :D
<FromGitter> <naqvis> β€˜meta: Metadata. This is currently not used for anything.’
<FromGitter> <naqvis> lol
<oprypin> u can only hope that "currently" means "when this was last updated" so like 3 years ago
<oprypin> I'd check the actual thing but I'm afk
<jhass> sure whenever you got time
<jhass> I can't be arsed to sign up for an oauth application just to check :D
<jhass> how are they making money anyhow? I see no pricing page
sorcus has quit [Quit: WeeChat 2.8]
sorcus has joined #crystal-lang
<FromGitter> <naqvis> their parent company (gitlab) might be making money lol
sagax has quit [Remote host closed the connection]
<jhass> oh it's gitlab? meh
<jhass> that explains the ugly UI :P
sz0 has joined #crystal-lang
<straight-shoota> They had the UI already before Gitlab bought them
<straight-shoota> But honestly, I don't think the Gitlab UI is too bad
alexherbo2 has quit [Ping timeout: 240 seconds]
<jhass> it lacks any visual guides, everything is too flat and without borders for me
zorp has joined #crystal-lang
Mikaela has quit [Quit: Mikaela]
Mikaela has joined #crystal-lang
sagax has joined #crystal-lang
alexherbo2 has joined #crystal-lang
sorcus has quit [Quit: WeeChat 2.8]
sorcus has joined #crystal-lang
<oprypin> github just hasn't gotten around to making everything flat
<raz> i don't think they would make that mistake
<raz> the flat fad gladly mostly ended 2014ish
cloaked1 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
<FromGitter> <ImAHopelessDev_gitlab> i hope they never do
alexherbo2 has joined #crystal-lang
HumanGeek has quit [Read error: Connection reset by peer]
HumanGeek has joined #crystal-lang
<FromGitter> <wrq> ```s = Iterator(Int32).of {[1,2,3].sample``` is there something like Enumerator.produce in Crystal?
<FromGitter> <wrq> I thought that was it, I'm a little confused, the api docs don't seem to mention a shortcut for quick iterators
<FromGitter> <Blacksmoke16> whats the goal?
<FromGitter> <wrq> an endless sequence of whatever block I pass it
<FromGitter> <wrq> the result of evaluating that block, over and over
<FromGitter> <wrq> that just loops over a collection
<FromGitter> <wrq> I need the block evaluated each time
<FromGitter> <Blacksmoke16> i.e. get a new random value from the array each time `.next` is called?
<FromGitter> <Blacksmoke16> isnt that what your code already does?
<FromGitter> <wrq> uhhh, yes
<FromGitter> <wrq> sorry, I had tried .take
<FromGitter> <wrq> and it's not defined for SingletonProc, I didn't bother to check .next
<FromGitter> <Blacksmoke16> singletonProc?
<FromGitter> <Blacksmoke16> ah, prob an internal type
<FromGitter> <wrq> right
<FromGitter> <wrq> I can use .first(n) to get however many I need
<FromGitter> <wrq> thank you
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <wrq> πŸ‘
<FromGitter> <jwoertink> I have a tempfile instance. If I call `gets_to_end`, I get a Closed stream IO::Error. How do I get the contents of that?
<FromGitter> <jwoertink> It seems if you call `read`, you need to know the exact amount of Bytes
<FromGitter> <watzon> How did you create the tempfile? The closed stream error seems to suggest that the file is closed.
<FromGitter> <jwoertink> it's from sending through a multipart form
<FromGitter> <jwoertink> I sent the file to the server, the server sees the tempfile, and now I want to read it on the server side
<FromGitter> <Blacksmoke16> `File.read`?
<FromGitter> <watzon> I was gonna suggest that
<FromGitter> <jwoertink> then use `tempfile.path`?
<FromGitter> <Blacksmoke16> sure
<FromGitter> <watzon> Yepp
<FromGitter> <jwoertink> ah ok. Well, it's not pretty, but that works
<FromGitter> <jwoertink> Thanks!
<FromGitter> <watzon> Might be able to come up with something better if we could see some example code
<FromGitter> <watzon> If you have access to the File instance then you should be able to read from it, unless it's been closed
<FromGitter> <watzon> If you are creating the temfile using a block though, it closes as soon as the block exits
<FromGitter> <jwoertink> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ec18c1890f6db31bef12842]
<FromGitter> <jwoertink> that's the tempfile
<FromGitter> <Blacksmoke16> > If you are creating the temfile using a block though, it closes as soon as the block exits
<FromGitter> <Blacksmoke16> ^
<FromGitter> <jwoertink> Yeah, just noticed that
<FromGitter> <watzon> Yeah that's the problem
<FromGitter> <jwoertink> hmm... But the file has to be closed at some point, right?
<FromGitter> <watzon> Just don't use the block syntax and you'll be good
<FromGitter> <watzon> It does have to be closed at some point ideally
<FromGitter> <watzon> If you need the file to stay open you can close it in your class' finalize block, or just close it after you're done using it
<FromGitter> <jwoertink> ```post "/data" do ⏎ data = @tempfile.gets_to_end ⏎ ⏎ # ... ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5ec18c9716ae6a315f24c0f8]
<FromGitter> <jwoertink> so like in a scenario like this
<FromGitter> <jwoertink> let's say the tempfile was created without the block, then it would be up to the user to close the file before the action is completed, right?
<FromGitter> <jwoertink> Actually, that just gave me an idea
<FromGitter> <watzon> Well they'd just have to close it at some point, or they can keep it open. The file will be closed by the OS on exit, so if it doesn't get closed it's not the end of the world, but it will be using unnecessary memory.
<FromGitter> <kinxer> Also, I think there's a maximum number of files you can have open at one time, which will cause a runtime exception (and probably crash your program).
<FromGitter> <watzon> Yeah for sure. So if you're opening and writing to files in a loop it can cause issues.
<FromGitter> <jwoertink> Yeah, that makes sense
<FromGitter> <kinxer> Or if you just have a bunch of instances that have open tempfile instance variables.
<FromGitter> <didactic-drunk> `GC`will also close files. You can't count on it except for one off uses because of the os limit @kinxer mentioned.
<FromGitter> <kinxer> You could also store the path to the file. That might be more stable, but I don't know what kind of guarantees you have that the OS will keep the file around.
<FromGitter> <kinxer> I admittedly don't know much about how the OS treats temporary files.
<FromGitter> <didactic-drunk> @kinxer It doesn't.
<FromGitter> <didactic-drunk> Temp files are handled purely by the `Tempfile` class. If `close` or it's `finalizer` isn't called it doesn't get deleted.
<FromGitter> <didactic-drunk> Oh whoops, I'm thinking of ruby.
<FromGitter> <kinxer> Crystal won't delete a tempfile on close, right? That seems unuseful.
<FromGitter> <Blacksmoke16> would want to call `.delete` on it when you're done
<FromGitter> <didactic-drunk> @kinxer That behavior seems bug like.
<FromGitter> <didactic-drunk> I expect `close` to delete.
<FromGitter> <kinxer> Why? How would you use a temporary file that was deleted when you closed the file descriptor?
<raz> you rewind before closing it
<FromGitter> <kinxer> No, I'm asking what the point is. Would it only be for other programs to read while your program just holds onto a file descriptor for no reason until it wants to stop holding onto it?
<raz> it's good practice to not leave temp files behind (temp space is finite)
<FromGitter> <kinxer> I mean, yeah. But I don't see why you'd need the file descriptor to be open the whole time the temporary file is in use.
<FromGitter> <kinxer> Or, rather, the whole time you want the temporary file to be available.
<raz> well, that's kinda the definition of a temp file. it exists while you use it, then disappears
<raz> if the runtime doesn't delete it on close it would have to keep track of them, delete them at_exit, etc.
<raz> would be more complicated, less reliable
<raz> plus if you create many or large ones and your process is long running, you could accumulate a lot of cruft
<FromGitter> <kinxer> Sure. I just still don't get what the use case is for a temporary file that you can never close the file descriptor for until you're done with it. I think the way it currently seems to implemented ("It is encouraged to delete a tempfile after using it" using `#delete`) makes sense; you can choose to keep track of it without holding on to open file descriptors if you needs lots of temporary files.
<raz> well, i think the main benefit is that it's harder to forget to delete it
<raz> common use case is write temp file, spawn sub-proc that reads it (all in a block so you don't have to remember closing or deleting it)
<raz> that close/delete part is often done wrong, (e.g. no ensure for when exceptions are raised)
<raz> and then you get in trouble with the angry sysadmin who's annoyed cause your little thinger ate up all his /tmp
<FromGitter> <kinxer> What kind of data would you write to a file and read in a fiber that you wouldn't rather just keep in memory? Or by "sub-proc" are you referring to some other program that you may or may not have written?
<raz> yup, the latter
<raz> user uploads image, you feed it to imagemagick or such
<raz> or if you're exchanging large data between fibers there could also be cases where a temp file is helpful
<FromGitter> <kinxer> Okay, yeah. I think I get it now.
<FromGitter> <kinxer> I think I'd prefer a way to clearly mark that you want a tempfile you're instantiating to delete on close rather than just changing the behavior (or even changing the behavior but allowing the current behavior with a clear option).
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
<raz> ah yup, a breaking change could surprise people in a bad way
<raz> i think the current way mirrors go-lang behavior
<raz> whereas python/ruby/others delete-on-close by default
_ht has quit [Quit: _ht]
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
hamoko[m] has joined #crystal-lang
HumanGeek has quit [Ping timeout: 246 seconds]
HumanGeek has joined #crystal-lang
HumanGeek has quit [Read error: Connection reset by peer]
<oprypin> hold up. so we have `Iterator.of` and it seems to be a way to turn a yielding function into an iterator. why do people not know about this?
<jhass> because it causes segfaults? :D
<jhass> also no docs
<jhass> Ah, no it's not like Enumerator.new
<jhass> it just tkes a block/proc and calls it for each next
<jhass> so it's just defining an iterator with a simple next body
<jhass> proper enumerator the block yields all the values
<jhass> at once
deavmi has quit [Quit: Eish! Load shedding.]
<jhass> and the enumerator suspends it inbetween
<jhass> so yeah, there's some overlapping usecases given you can pass a closured block. But not exactly the same
deavmi has joined #crystal-lang
<oprypin> jhass, well it's not exactly, but with the fact that it's a closure you get pretty close. so like it covers the use case where you would've written `def foo; some_initialization; while true; some_logic; yield stuff; break if condition; end; end`
alexherbo2 has quit [Ping timeout: 260 seconds]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<straight-shoota> any thoughts on naming a HTML sanitation shard? I went with `sanitize` so far...
<oprypin> jhass, well what do you know, they do expose the thread data, undocumented json key parentId. https://bpa.st/RKYA - . but uhhh doesn't mean i'll actually do anything about it. realistically do you think people will bother including a thread id in irc
<FromGitter> <Blacksmoke16> Probably a fine name given its purpose
<FromGitter> <Blacksmoke16> @straight-shoota its okay that `LIBRARY_PATH` for libgc is overridden in the build image?
<FromGitter> <Blacksmoke16> but the alpine one also sets something in the build image, https://github.com/Blacksmoke16/distribution-scripts/blob/build-libgc/docker/alpine.Dockerfile#L53 i imagine we need both or?
zorp has quit [Ping timeout: 260 seconds]
<straight-shoota> yeah, both should prob take the existing LIBRARY_PATH in account
<FromGitter> <Blacksmoke16> does it take multiple paths like `PATH`?
<FromGitter> <Blacksmoke16> or?
<straight-shoota> of course
<oprypin> yes it does
<oprypin> taking existing into account is really ugly though
<straight-shoota> wouldn't be much useful without that^^
<FromGitter> <Blacksmoke16> separated by `:`?
<oprypin> yes
<FromGitter> <Blacksmoke16> just like update the build image one to be like `ENV LIBRARY_PATH=/bdwgc/.libs/:/usr/lib/crystal/lib/`?
<straight-shoota> Yeah, that's probably better
<FromGitter> <Blacksmoke16> πŸ‘
<straight-shoota> still need to keep LIBRARY_PATH=/bdwgc/.libs/ for the runtime image, though
<FromGitter> <Blacksmoke16> yup
<straight-shoota> re/ sanitize shard name: I'm just writing the documentation
<straight-shoota> realised it's actually more like a general purpose HTML/XML transformation shard, with main purpose on HTML sanitization
<straight-shoota> so maybe a more general name might be better...
<straight-shoota> altough sanitization is probably the lion share of use cases
<oprypin> straight-shoota: for inspiration: https://www.thesaurus.com/browse/sanitize πŸ˜„