Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How in Dart get command line arguments outside of the main method? #18369

Closed
DartBot opened this issue Apr 22, 2014 · 19 comments
Closed

How in Dart get command line arguments outside of the main method? #18369

DartBot opened this issue Apr 22, 2014 · 19 comments
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue library-io type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Apr 22, 2014

This issue was originally filed by andrew.m...@gmail.com


Question on StackOverflow.com:

http://stackoverflow.com/questions/23221556/how-in-dart-get-command-line-arguments-outside-of-the-main-method

In C# langauge exists global system variable for this purpose.

Environment.CommandLine
This property provides access to the program name and any arguments specified on the command line when the current process was started.

Dart is asynchronous langauge. It allows self starting processes.

void main() {
  task("foo", callback1);
  task("baz", callback2);
}
Package tasks.

void task(String name, action()) {
  schedule();
  addTask(name. action);
}

void schedule() {
  // Here we start timer if it not started.
  // This timer will get cmd line arguments
  // And executes task specified in cmd line arguments
}

===================================
I want implement in Dart build tool similar to Ruby rake.
For this purpose I implemented the "globbing" package.

I need get the command line arguments from "dart:io" "Platform" class.

Can you implement this quickly?
Similar to this code:

class Platform {
  static List<String> get arguments;
}

@iposva-google
Copy link
Contributor

Added Area-IO, Triaged labels.

@andersjohnsen
Copy link

cc @lrhn.

@lrhn
Copy link
Member

lrhn commented Apr 23, 2014

I don't believe there are any current plans to bring back a way to get the arguments to main from outside of main. If your main function needs the arguments, it should either process them, or store them somewhere.

If you are not in control of the main function (e.g., as a library), you can use a -D option to pass in configuration options.
  Run your program as:
    dart -Darg=val program.dart
  and inside your code do:
    var argVal = const String.fromEnvironment("arg");
    print(argval); // prints "val".

This is a way to pass configuration options to your program on the command line.

Normal command line arguments are only intended as arguments to the main function, not to the system itself.


Removed Type-Defect label.
Added Type-Enhancement label.

@andersjohnsen
Copy link

As lrn@ said, this is currently not planned. Just like most other programs, arguments are received by the main method. It can then choose what to do with them.

lrn@ does suggest a quite viable work-around. This should be considered if there is an absolute need for sharing 'arguments' as described.


Added NotPlanned label.

@lrhn
Copy link
Member

lrhn commented Apr 23, 2014

For this particular case, you would need to add to your task package an initialization function that takes the parameters.
I'd actually prefer to make the task package an object rather than a library:

    main(args) {
      new Task(args)
          ..task("foo", callback1)
          ..task("bar", callback2);
    }

or the more imperative:
   
    main(args) {
      initializeTasks(args);
      task("foo", callback1);
      task("bar", callback2);
    }

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


Normal command line arguments are only intended as arguments to the main function, not to the system itself.

Your don't think about that the "Why other platforms does not consider that 'command line arguments are only intended as arguments to the main function'?".

main(args) {
  initializeTasks(args);
  task("foo", callback1);
  task("bar", callback2);
}

"initializeTasks(args)" seems here as if it were happening in the last century in Fortran language.

With this approach, you will not have a chance to compete with other languages.

Go language
===========
func main() {
    fmt.Println(len(os.Args), os.Args)
}

===========

Rust language
===========
fn main() {
  let args = os::args();
  println!("The first argument is {}", args[1]);
}

===========
C# language
===========
class Sample {
  public static void Main() {
    Console.WriteLine();
    String[] arguments = Environment.GetCommandLineArgs();
    Console.WriteLine("GetCommandLineArgs: {0}", String.Join(", ", arguments));
  }
}

===========
Ruby language
===========
ARGV.each do|a|
  puts "Argument: #{a}"
end

===========
Python language
===========
import sys

print(sys.argv)

===========
PHP language
===========
foreach($argv as $value)
{
  echo "$value\n";
}

===========
Node.js language
===========
process.argv.forEach(function (val, index, array) {
  console.log(index + ': ' + val);
});

===========
Dart language
===========
print("Dart Team says: We are sorry, this is not possible because we better than other know that this is unneeded.");

@lrhn
Copy link
Member

lrhn commented Apr 23, 2014

There are plenty of examples in both directions.

The main problem with a global way to access command line arguments is exactly that it is global, and therefore inherits all the problems of global variables.

If a library is built to read a global Options.commandLine, then it is fixed to only be able to get the values from there. If instead it takes a list of strings as an argument, those can come from anywhere. It makes unit testing and mocking much easier, and increases compositionality.

It also makes it possible to call a main function from another library with your own choice of arguments, instead of only being able to pass them on the command line or through spawning an isolate.

There is nothing you can't do with one approach that you can't do with another, you just have to explicitly pass the arguments to whoever needs them. So, yes, it is indeed "unneeded" (but then, most of everything is when your language is Turing complete) and we have chosen another approach than the languages you picked out - the same approach as a number of other languages that you didn't list.

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


It also makes it possible to call a main function from another library with your own choice of arguments, instead of only being able to pass them on the command line or through spawning an isolate.

Yes. I want get real arguments that given by the OS when it executes the the OS PROCESS but not the "surrogate" arguments that can be passed to "main" in each THREAD.

This is a big difference and if it not so often used then this not means that this is unneeded.

Command line arguments and arguments that passed to the "main in Dart can differs but the real arguments can be only one that goes from OS (Dart VM in our case).

Why you want hide them?
I'm not going to confuse them. I understood you perfectly.

P.S.

This is not a language approach. This is a platform specific approach.
Arguments passed to "main" is a language approach.
But missing possibility to get process (sub)arguments is an approach of Dart platform approach.

P.S.
My example above does not uses language approach (eg. main).
They was platform and their libraries approach.

Example.

===========
Node.js language
===========
process.argv.forEach(function (val, index, array) {
  console.log(index + ': ' + val);
});

Not a language specific because uses "process.argv".

Dart platform has no moral right to deprive me of the opportunity to receive this information in any other way (not through "main").

This is very bad approach to think that if you not need them then YOU MUST HIDE them deeply inside virtual machine.

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


===========
Node.js language
===========
process.argv.forEach(function (val, index, array) {
  console.log(index + ': ' + val);
});

Not a language specific because uses "process.argv".

P.S.

Honestly, I was not sure that you are able to understand me because you chose to hide them.

You you not feel difference between two different things such a following:

  • Command line arguments passed to OS process. The part of the Dart VM argument after the script path (script argeument).
  • Surrogate arguments from parameters of the "main" method that not always real "command line arguments" given by the user to OS program.

You you not feel difference between two different things such a following:

  • Command line arguments passed to OS process. The part of the Dart VM argument after the script path (script arguments).
  • Surrogate arguments from parameters of the "main" method that not always real "command line arguments" given by the user to OS program.

How can we talk about something you after such a misunderstanding of each other?
Can exists the hard stuff. Can misunderstand something because of poor knowledge of a foreign language (for example, me and English language).

But how can you not understand the basic concepts, I do not understand you.

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


print(Platform.executableArguments);

Output:
[--enable-checked-mode, --debug:60514]

Whay you truncate them.

How I get full arguments. I want parse them.

/home/andrew/tools/dart/dart-sdk/bin/dart --enable-checked-mode --debug:60514 test.dart

But I just want get the following part "test.dart foo --baz".

But I agree, and full part

/home/andrew/tools/dart/dart-sdk/bin/dart --enable-checked-mode --debug:60514 test.dart

Because I can parse it and find information which I need.

Why you hide this full argrumnts?
Security? Not sure...

Platinum rule:
Dart platform (not a language) should not be like everyone else.
Other developers think about others, we primarily think only about themselves.
That what do not requires to us, do not requires to anyone.

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by @seaneagan


@LRN: Global variables do not prevent a library from taking the state as an argument, but they do allow libraries to provide a sensible default value for the state argument for production code or scripts that don't need to mock out, or otherwise inject the state. Of course, not providing the global variable does force people to make their code testable.

But, it seems weird to me that all the other state passed in from the computing environment is available through global state, including all the Platform static variables, and -D parameters.

This would be nice for:

http://pub.dartlang.org/packages/unscripted

Example:

    main() => declare(script).execute();
vs.
    main(arguments) => declare(script).execute(arguments);

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


Example:

main() => declare(script).execute();
vs.
main(arguments) => declare(script).execute(arguments);

The same thing.

void main() {
  task("foo", callback1);
  task("baz", callback2);
}

vs

main(args) {
  initializeTasksAsSuggestedLrn(args);
  task("foo", callback1);
  task("bar", callback2);
}

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


No problem. I can write it by himself using shell.
On Linux I found the way:

ps-p XXXX-o cmd =

On Windows I also can solve this.
I even can write the library for that. But why? (not a question).

Now two basic questions to very smart @­ lrn.

  • WHY I SHOULD TO DO THIS IN DART MANUALLY?
  • Why I can do this w/o problems in the other platforms?

Another question that you can not answer:
How much time you need to answer on the two above questions?

@DartBot
Copy link
Author

DartBot commented Apr 23, 2014

This comment was originally written by andrew.m...@gmail.com


@seaneagan1

http://pub.dartlang.org/packages/unscripted

I also trying to write similar.
At beggining I use also annotations.
But I consider the best way to get declaration avalaible to other.

Assume I want write in Dart shell similar to Spring "roo".
Q: How it may know command and options of other pluggable shells?
A: They should be always available as config files.

Example:

dartshell.yaml
=========
name: foo
commands:
  cmd1:
    options:
      opt_list:
        allowMultiple: true
      opt_string:
      opt_flag:
        isFlag: true
=========

Now source code

var helper = new ArgsHelper<MyProgram>();
helper.run(args);

class MyProgram {
  // Associated with command "cmd1"
  // opt_list, opt_string and opt_flag associated with their
  // options in "dartshell.yaml"
  void cmd1(List<String> opt_list, String opt_string, bool opt_flag) {
  }
}

@kevmoo
Copy link
Member

kevmoo commented May 14, 2014

Removed Area-IO label.
Added Library-IO label.

@DartBot
Copy link
Author

DartBot commented Apr 20, 2015

This comment was originally written by @kaendfinger


I'm going to challenge myself by figuring this out.

@DartBot
Copy link
Author

DartBot commented Apr 20, 2015

This comment was originally written by @kaendfinger


https://codereview.chromium.org/1098063003

@lrhn
Copy link
Member

lrhn commented Apr 21, 2015

Issue #22466 has been merged into this issue.

@DartBot
Copy link
Author

DartBot commented Apr 21, 2015

This comment was originally written by @kaendfinger


In my personal view, the benefits outweigh the negatives. Maybe sometime in the future this decision can be re-evaluated once usage of Dart is more vast.

@DartBot DartBot added Type-Enhancement library-io closed-not-planned Closed as we don't intend to take action on the reported issue labels Apr 21, 2015
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed priority-unassigned labels Mar 1, 2016
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue library-io type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants