Is there any equivalent to C's main() or python's if-main statement?


#1

Is there some equivalent to C’s int main() or python’s if __name__ == "__main__":? Basically I want to call a method when my shard is executed but not if the shard has been required as a library. Is the only solution to create a separate file, say, cli.cr with contents like this…?

require "library"
Library.command_line_interface ARGV

#2

I created a PR to implement this. There you will soon find opinions about this: https://github.com/crystal-lang/crystal/pull/7466

Edit: added the word “soon” because just right now there are no opinions :slight_smile:


#3

One of the core developers of the language creates a PR and gets 6~ downvotes. All because he listened to a user on the forum and wanted to help. That’s pretty sad and doesn’t sit well with me at all.


#4

He explicitly stated that the PR was meant as an experiment to ask for opinions. And I’m pretty sure he was well aware that it was relatively unlikely that this feature would make it into the compiler. So, I don’t think there has been any harm done.


#5

I also didn’t want to merge it. But if many people liked it then there was a chance to merge it (probably as a specific macro call).

I just wanted to have real opinions/reactions against a working PR: if it was liked then we could merge it. If not then it serves as a document with reasons for future people asking about this feature.


#6

Oh I agree, giving opinions and criticism about the PR is great! But I believe downvoting it is not appropriate or deserved. Just my 2 cents


#7

A :-1: reaction is just an expression of opinion about the subject (which was explicitly asked for), and not defaming the author’s effort. I don’t think that should be interpreted as rude.


#8

I totally agree with @straight-shoota, I take it as an expression of an opinion regarding the subject of the given PR, there’s no need to take it to yourself.


#9

I don’t think it’s necessarily defaming, I just think it’s not appropriate / deserved. Especially considering the core developer listened to a user’s problem and wanted to implement a solution. That’s commendable behavior, and certainly doesn’t warrant a thumbs down.


#10

Please don’t misinterpret the meaning. It’s simply an expression of opinion.
Do you now any practical alternative to convey this meaning differently? (Without everyone posting a comment saying “I’m against this proposal”)


#11

I’m not misinterpreting the meaning :/

The practical / alternative way is to respond politely / formally / professionally and show criticism about the proposal? Which is what happened! But to downvote, why?


#12

Because it gives a much better overview. If everybody comments, likely with the same arguments as before, also often more than once with a changed opinion, it’s very hard to keep track and a good overview of the community’s feeling towards a particular issue.

So for example for me I did both, downvote and, given my arguments were not presented yet by anybody else, add a comment explaining why I’m against this. If somebody already had presented these same arguments I wouldn’t have commented and just kept to the downvote.


#13

Downvotes on reddit mean “this is not a quality post”. Thumbs down reactions on github mean “I disagree with this comment”.


#14

There is nothing to “disagree with” though. The PR was made in light of a user having a problem. That’s commendable behavior, not “oh, I can disagree with this, let’s thumb down a core developer’s post!”. That’s not right. Doesn’t have to be a core developer either, anyone for that matter.


#15

But my “problem” was simply not knowing the conventions of the language. The disagreement was with adding a new feature to the language and how that feature would be implemented. I look forward to their being a convention for this idea, but I respect people’s decision that one convention doesn’t fit with the rest of the language.

I would definitely prefer it if there were a conventional place to put files that will be compiled to binaries and for “shards build” to create said binary, but I kinda agree that the way I suggested doesn’t fit very well.


#16

Oh for sure, but taking in the context of the entire post within the PR, where it specifically links to this forum thread… and then seeing it have -6+ thumbs down… feels weird.

I would never in a million years thumbs down a core developer in any repo; merely because the PR came to fruition over trying to implement a solution from a question / problem a user expressed on their forum.


#17

Don’t worry too much. I expected downvotes. I don’t want this feature in the language. So each downvote makes me slightly happier. Also, downvotes are just bits in a server. And you can always flip your head and they become upvotes. It all depends on how you take it.


#18

Ruby has the somewhat awkward

if __FILE__ == $0

FWIW :)


#19

At the risk of performing some minor thread necromancy, I’d like to share the convention for this kind of thing that I’ve been using. This was influenced by looking through the code in Scry, specifically scry.cr.

The project directory structure has the following form:

  • src/
    • library_module_name/
    • project_name.cr (or maybe “driver.cr”)
  • spec/

Then in your project_name.cr (again, or driver.cr or whatever):

require "./library_module_name/*"

module LibraryModuleName
  def self.run
    # do special things like show your CLI
  end
end

LibraryModuleName.run

This works really well when using the OptionParser to create a CLI that can go in another file, like src/configuration.cr, and be required and called in the driver.

I don’t know if this is actually the kind of solution you’re looking for, but I’ve found that it allows for pretty nice separation of the library from the standalone executable.