9

I was wondering why the people who wrote the File library decided to make the arguments that determine what mode the file is opened in strings instead of symbols.

For example, this is how it is now:

f = File.new('file', 'rw')

But wouldn't it be a better design to do

f = File.new('file', :rw)

or even

f = File.new(:file, :rw)

for example? This seems to be the perfect place to use them since the argument definitely doesn't need to be mutable.

I am interested in knowing why it came out this way.


Update: I just got done reading a related question about symbols vs. strings, and I think the consensus was that symbols are just not as well known as strings, and everyone is used to using strings to index hash tables anyway. However, I don't think it would be valid for the designers of Ruby's standard library to plead ignorance on the subject of symbols, so I don't think that's the reason.
Community
  • 1
  • 1
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 5
    This is probably just a historic artifact going all the way back to `fopen` in libc. – mu is too short Sep 24 '11 at 21:10
  • 7
    Are you suggesting that a unique symbol be defined for each valid permutation of `File.new` modes (`r`, `w`, `+`, `a`, `b`, `t`)? – Gabe Sep 24 '11 at 21:30
  • Great question. There are constants like `File::RDWR` and `File::CREAT` that you can use, but I can't find documentation about it. The `File` [documentation](http://www.ruby-doc.org/core/classes/File.html) uses these constants, but does not explain them. – rdvdijk Sep 25 '11 at 12:56

2 Answers2

2

I'm no expert in the history of ruby, but you really have three options when you want parameters to a method: strings, symbols, and static classes.

For example, exception handling. Each exception is actually a type of class Exception.

ArgumentError.is_a? Class
=> True

So you could have each permission for the stream be it's own class. But that would require even more classes to be generated for the system.

The thing about symbols is they are never deleted. Every symbol you generate is preserved indefinitely; it's why using the method '.to_sym' lightly is discouraged. It leads to memory leaks.

Strings are just easier to manipulate. If you got the input mode from the user, you would need a '.to_sym' somewhere in your code, or at the very least, a large switch statement. With a string, you can just pass the user input directly to the method (if you were so trusting, of course).

Also, in C, you pass a character to the file i/o method. There are no Chars in ruby, just strings. Seeing as how ruby is built on C, that could be where it comes from.

kojaktsl
  • 122
  • 4
1

It is simply a relic from previous languages.

weexpectedTHIS
  • 3,358
  • 1
  • 25
  • 30
  • I disagree. Could you back up your claim with examples and any statements from the creators? – Austin Henley Sep 25 '11 at 21:22
  • 1
    I'm not going to look up the docs for all older languages and show you they all use this string format, but here is one example from another web language: http://us3.php.net/manual/en/function.fopen.php – weexpectedTHIS Sep 25 '11 at 21:35
  • Ok but why did PHP do it? Is it because PHP as a language is based heavily around strings? Is it because PHP doesn't support symbols like Perl? Is it because...? What im getting at is that you provide no evidence that this is an answer rather than your opinion. – Austin Henley Sep 25 '11 at 23:52
  • 2
    @Azh: This practice goes all the way back to [C's `fopen` function](http://linux.die.net/man/3/fopen), which all of these languages are descended from. Does that mean that this is the reason? No. But it is strong evidence. – Antal Spector-Zabusky Sep 26 '11 at 00:31