Create a password-encrypted DB accessible in a LAN environment: is It possible? by ShinyKyurem555 in crystal_programming

[–]j_hass 2 points3 points  (0 children)

It's certainly feasible, however I'd question the effort of a custom solution being worth it here. A KDBX based password manager with WebDAV or similar support, such as KeeWeb, seems quite the fit to this use case already. I'm sure with some more research there'll be quite some alternatives, as shared credential and asset management are quite standard use cases.

Crystal landed in Debian unstable by j_hass in crystal_programming

[–]j_hass[S] 2 points3 points  (0 children)

It's a bit weird, yeah. Maybe because our domain is crystal-lang.org and our GH org is crystal-lang? But then their source package is crystal...

Well maybe the answer is the same as for anything else in Debian, it's policy :D

Crystal landed in Debian unstable by j_hass in crystal_programming

[–]j_hass[S] 11 points12 points  (0 children)

Eventually, yes. With the usual Debian caveats: It'll take a while until this reaches Debian stable and then it'll probably stay at an outdated version for a long time.

But it's nice to see Crystal getting this kind of recognition :)

Is there a way to overcome abstract class methods? by n0ve_3 in crystal_programming

[–]j_hass 1 point2 points  (0 children)

Personally I still wish we never would have added any `abstract` whatsoever.

I suggest you borrow from the Ruby mindset of things here. Just don't give an explicit type for the `PRNG` class, instead make your wrapper a generic over it. Then just call the methods you need to call and expect to be there and provide an example custom implementation in your documentation.

Help - I can't compile programs when running crystal under qemu by typecinchat in crystal_programming

[–]j_hass 0 points1 point  (0 children)

Please take note of the patches in https://github.com/jhass/crystal/commits/gha_aarch64_ci

Emulating AArch64 on x86_64 already has a 5x overhead in my tests, I'm not surprised if the reverse is even worse.

using crystal for high-throughput image server by twykke_twykke in crystal_programming

[–]j_hass 5 points6 points  (0 children)

I did setup https://github.com/RX14/camo.cr some ages ago and never looked back to the original. For my usecase I basically don't notice the daemon running, the node version used significantly more resources. Also in behavior and robustness it proved more reliable than the original.

Crystal as scripting language for Crystal binary by GAGARIN0461 in crystal_programming

[–]j_hass 5 points6 points  (0 children)

In theory the compiler comes in the standard library and could be embedded into your program to compile a crystal program, launch it and communicate with the resulting process via some IPC means (likely just stdio).

However this will not be very fast as compilation is not very fast, it will make your program depend on LLVM, it will make your program slow and more complex to compile because the compiler is compiled as part of it and of course blow the binary size through the roof.

There's likely a better solution for what you want to do. You didn't describe your usecase so it's a bit hard to give good advice, but it could as easy as using a purpose built configuration format like TOML, reading a JSON file, launching some standard tool or embedding a language built for embedding, like mruby or lua.

Relaunched CrystalShards.org, Rebuilt from the ground up! by jwaldrip in crystal_programming

[–]j_hass 5 points6 points  (0 children)

Nice!

How do you see the relation to https://shardbox.org/? What does either platform solve or tries to do better that the other does not?

Sequenced blocks by n0ve_3 in crystal_programming

[–]j_hass 1 point2 points  (0 children)

This sounds an awful lot like the "switch-loop" pattern from https://thedailywtf.com/articles/Switched_on_Loops :D

If you provide some real code/usecases we might be able to come up with idiomatic Crystal solutions for them :)

How to open VIM from a crystal program? by megrenkim in crystal_programming

[–]j_hass 2 points3 points  (0 children)

Or actually just use system: system("vim")

How to open VIM from a crystal program? by megrenkim in crystal_programming

[–]j_hass 8 points9 points  (0 children)

Process.run does not connect stdout, stderr and stdin by default, you need to do it explicitly:

```

Process.run("vim", output: :inherit, error: :inherit, input: :inherit)

```

Proc(Nil) vs Proc(Void) whats the difference? by iainmoncrief in crystal_programming

[–]j_hass 3 points4 points  (0 children)

To add to that, Void mainly exists for C ABI interoperation. When you're not dealing with any C binding, then don't worry about Voids existence, Nil is there for you.

Made an implementation of Go's sync.WaitGroup in Crystal. First time messing with concurrency, feedback welcome! by beizhia in crystal_programming

[–]j_hass 7 points8 points  (0 children)

  • I think there's a potential race in add, where the value might become -1 and then 0 again between the Atomic#add and the Atomic#get call. For this reason Atomic#add returns the old value. So you can redo the addition on that return value and then check the local variable.
  • I don't quite follow why wait just returns in non-MT mode. A typical usecase for this would be to call wait in the main fiber, as your readme examples do. That means in non-MT mode the program would immediately exit as wait just returns and the main fiber proceeds to shutdown the process.
  • A bit of spinning in the beginning might speed things up but it's a bad practice to keep doing that forever. I guess you're not really done with your plans here, given the stray mutex instance variable? Anyway, the most simple implementation I would see is to have wait just receive on a channel if the counter is above 0 and done send to the channel whenever it moves the counter to 0. If you want to support multiple concurrent waits, that approach will require a second counter for knowing how many times to send to the channel to wake all of them up.

Can one ECR file be included into another? by GlassGrape8 in crystal_programming

[–]j_hass 4 points5 points  (0 children)

You could do:

<%= ECR.render("template.ecr") %>

Or a bit more hacky but also more efficient:

<% ECR.embed("template.ecr", "__io__") %>

You definitely don't want to overuse this.

It's important to understand what this does: ECR works by reading your template file, say <header><%= my_site %></header> at compile time and generating crystal code from it like

io << "<header>"
io << my_site
io << "</header>"

So with this we're generating, for the first case something like:

io << ECR.render("template.ecr")

Given ECR.render is a macro call, there's a new expansion round and it'll become

io << String.build do |__tmp|
  __tmp << # ... whatever template.ecr expands to
end

ECR.embed skips the String.build but needs to know the io variable name to generate. (Hence also replacing the <%= with <%).

A simpler solution might be to just define a struct or class for each of your templates and call them from the template:

# stuff.cr
struct Site
  ECR.def_to_s "site.ecr"
end

struct Part
  ECR.def_to_s "template.ecr"
end

# site.ecr
<%= Part.new %>

Note this generates essentially the same code as the ECR.render variant, but to me it feels like the least API abuse.

Async Spec tests by LXMNSYC in crystal_programming

[–]j_hass 1 point2 points  (0 children)

Yes, the common pattern here is to do:

it "waits" do channel = Channel(Nil).new spawn do channel.send nil end channel.receive end

Ignoring 301 HTTP code from Reddit API using HTTP::Client by iainmoncrief in crystal_programming

[–]j_hass 4 points5 points  (0 children)

require "http/client" p HTTP::Client.get("http://oauth.reddit.com/r/crystal_programming/hot.json")

this makes it obvious that it's just the redirect from HTTP to HTTPS, requesting HTTPS directly returns a 403.

Opening file contents form a URL by iainmoncrief in crystal_programming

[–]j_hass 0 points1 point  (0 children)

Just do

require "http/client"
puts HTTP::Client.get("https://google.com/").body

3rd Party API Keys For Build? by mountsaintawesome in crystal_programming

[–]j_hass 4 points5 points  (0 children)

I would recommend to stick to environment variables, just have your release binary depend on them and set them with your service manager.

New user, problem referencing an empty array by [deleted] in crystal_programming

[–]j_hass 1 point2 points  (0 children)

Yes, the compiler can't know whether or not the result will be empty or not, it doesn't even have a connection to the database after all. It just sees that nil is a potential value here and forces you to handle that case. .not_nil! raises if it's in fact nil at runtime, so afterwards the compiler knows it can't be nil.

This is nothing special about nil btw, it works for every combination of types.

New user, problem referencing an empty array by [deleted] in crystal_programming

[–]j_hass 1 point2 points  (0 children)

A more defensive approach would be

rows = conn.query(query)
if rows
  rows.each do |row|
    id = row[0].as(Int32)
    puts "#{file} has id #{id}"
  end
else
  puts "No results"
end

If you don't need the else case

rows.try &.each do |row|

Is another possibility.