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

class library: add File *read #2410

Merged
merged 7 commits into from
May 25, 2017

Conversation

telephon
Copy link
Member

Instead of requiring a callback function, it is much clearer to just
read from file and return the value.

Instead of requiring a callback function, it is much clearer to just
read from file and return the value.
@telephon telephon added this to the future milestone Oct 15, 2016
open the file, evaluate the function with the file as argument, and close it again. If the process fails, close the file and throw an error.

method::read
given a path, make a new temporary file, and read the contents, close the file and return them. By default, it calls link::#-readAllString::. If the process fails, close the file and throw an error.
Copy link
Member

@crucialfelix crucialfelix Oct 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh ? so you create a temporary file and then read the contents. That suggests that you just read an empty file. You just created it, then you read it. It is empty.

Then you close it and return "them" (who is them ? oh.. the contents)

ah, you are not creating a temporary file at all ! You just mean that internally you make a File object that does the reading. That is an implementation detail that the user should not be told about. The person calling this method does not need to know about the internals. Just the arguments and what is returned.

"make a temporary file" means this: https://www.google.de/search?hl=en&source=hp&q=make+a+temporary+file&btnG=Google-Suche&oq=&gws_rd=cr&ei=XmwIWMPPH-XX6ASXvaOIAQ

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, I just meant the file object!

the path (link::Classes/String::) that points to the file

argument::mode
the file mode to use.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only valid modes are "r" and "rb", correct ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. It may be argued that we don't need this option, but I don't know.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… I see you mean, I should add this information. Yes, I'll do so asap.

argument::selector
the method to be called on the file once it is open.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the valid methods that could be supplied here ? \readAllString , ... ?

@crucialfelix
Copy link
Member

Also it would be good to start each sentence with a capital letter.

@crucialfelix crucialfelix changed the title class library: easier file access class library: add File-read Oct 20, 2016
@crucialfelix crucialfelix changed the title class library: add File-read class library: add File *read Oct 20, 2016
@crucialfelix
Copy link
Member

looks great now, thanks !

nhthn
nhthn previously requested changes Oct 20, 2016
@@ -18,6 +18,11 @@ File : UnixFILE {
file = this.new(pathName, mode);
^{ function.value(file) }.protect({ file.close });
}
*read { arg pathName, mode = "r", selector = \readAllString;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about methodName instead of selector?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selector is already a convention from the various perform methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's a notion that comes from the smalltalk tradition. A symbol selects a method from the receiving object's vocabulary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -40,12 +40,35 @@ File.getcwd;
::

method::use
open the file, evaluate the function with the file and close it.
Open the file, evaluate the function with the file as argument, and close it again. If the process fails, close the file and throw an error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording nitpick: the tense here ("If the process fails, close the file and...") can be a bit confusing. Beginners may wonder if that's an instruction for something they need to do. I'd prefer the wording for e.g. mode ("Opens a file" vs "Open a file")

(By the way, this already is inconsistent throughout this file -- e.g. mkdir vs delete)

Copy link
Member Author

@telephon telephon Oct 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree on being painstakingly nitpicking with expressing things! The "traditional" standard in sc helpfiles is e.g. for round "Round to multiple of aNumber". Or sign "Answer -1 if negative, +1 if positive or 0 if zero." Or min "the minimum of the receiver and aMagnitude." But if we feel strongly about this, it can be changed of course, but this may mean many small changes …

I also agree that in this case it sound a bit like an instruction for the user! I'll change that.

Open the file, evaluate the function with the file as argument, and close it again. If the process fails, close the file and throw an error.

method::read
Given a path for an existing file, read and return the contents. By default, it calls link::#-readAllString::. If the process fails, close the file and throw an error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note as above

@adcxyz
Copy link
Contributor

adcxyz commented Dec 5, 2016

I agree that file opening and closing is boring admin for users.
Maybe the clearest option would be to have separate methods for all 'read entire file' methods?
Assuming text files are the default case, that could be:

File.read("path/to/file.txt");
File.readRTF("path/to/file.rtf");
File.readHTML("path/to/file.html");
File.readSignalFile.readSignal("path/to/file.sig");

Then users need not worry about read modes, cant erase files by accident etc.

For simple formatted text files, there is also the FileReader class and its subclasses.

@nhthn
Copy link
Contributor

nhthn commented May 14, 2017

I like this. Is it ready for merge?

@telephon
Copy link
Member Author

I wonder what you think about @adcxyz 's comments. It seems like a viable simplification.

@mossheim
Copy link
Contributor

I prefer @adcxyz's suggestion; it matches the API of the existing "readAllX" instance methods.

There is now a helpfile conflict with master, but should be trivial to resolve it.

@telephon telephon self-assigned this May 14, 2017
@telephon
Copy link
Member Author

agreed, I'll do these.

@telephon
Copy link
Member Author

telephon commented May 14, 2017

I've come up with these two simple methods:

*readString { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllString });
		^res
}
*readSignal { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllSignal });
		^res
}

If you want to strip away rtf, you can write:

File.readString(path).stripRTF

Does that look good?

@mossheim
Copy link
Contributor

Why not rtf and html?

@telephon
Copy link
Member Author

The interface readRTF had its purpose when the help system was still in RTF, same for HTML. So I just thought it's not really so important. Also semantically stripRTF seemed better, says what it does. It doesn't really give you a RTF representation back.

@mossheim
Copy link
Contributor

OTOH, it costs nothing to also make convenience functions for HTML and RTF, and this provides a more complete and consistent interface. I have personally used SC to read/strip HTML. "it's not really so important" seems like an odd argument to use given the triviality of these functions.

@telephon
Copy link
Member Author

probably it's harmless to just exactly replicate the instance read interface. For a moment I was put off by the fact that instead of just reading, it strips.

@telephon
Copy link
Member Author

telephon commented May 16, 2017

@brianlheim @adcxyz here is a new version, let me know if you like it, then I update the help.

The interface now simply matches the one of the instance methods:

       *readAllString { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllString });
		^res
	}
	*readAllSignal { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllSignal });
		^res
	}
	*readAllStringHTML { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllStringHTML });
		^res
	}
	*readAllStringRTF { arg pathName;
		var res;
		this.use(pathName, "r", { |file| res = file.readAllStringRTF });
		^res
	}

@mossheim
Copy link
Contributor

@telephon lgtm, thanks!

While `res` is a good generic name for a response or result, here
`string` is better.
Copy link
Contributor

@nhthn nhthn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any objections to this? aside from the conflict, it looks fine to me.

@mossheim
Copy link
Contributor

Help needs to be updated, and then I propose we merge :) Thanks!

@telephon
Copy link
Member Author

I tried to resolve it in the online editor, but somehow my browser doesn't show the GUI properly so I couldn't save the change. Maybe someone else can try?

@telephon telephon merged commit 17e132a into supercollider:master May 25, 2017
@mossheim
Copy link
Contributor

Still need to update the help file... it's referencing a non-existent method now.

@nhthn
Copy link
Contributor

nhthn commented May 25, 2017

i'll take care of it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants