How to look at image code in GNU Smalltalk? - smalltalk

how can I look at class / message code from within the GST command line interface?
I only know the #inspect message, but this shows only a definition or summary of the object, not the code.
Thank you :-)

You can use the "methodSourceString" method, like
st>(Object >> #printNl) methodSourceString
'printNl [
"Print a represention of the receiver on stdout, put a new line
the Transcript (stdout the GUI is not active)"
<category: ''printing''>
Transcript showCr: self printString
]'
However, the string will be printed with double quotes, which can be inconvenient for non-trivial code.
It's often simpler to just use a text editor, because almost always classes are contained in a single file. You can query the file name from the REPL, too:
st> Object methodDictionary anyOne methodSourceCode file
<File /usr/share/smalltalk/kernel/Object.st>

Related

How to explore a namespace in gnu smalltalk

When using gnu smalltalk (without emacs integration) what commands/process does one use to explore the contents of a namespace ? For example, I want to find out how to use the contents of NetClients but if I just type
NetClients examine
I get an enormous amount of text scrolling past. Is it even possible to pass this into something like less so I can scroll back and forth through it ? Ideally I'd like to see a list of classes for example, along with their general description. Then for those classes I'd like to be able to see only their selectors.
If you want to search in the text output when sending messages, I would simply redirect the output to file.
I would do the following:
gst -a > netclients_namespace.txt
type: NetClients examine
check the netclients_nemespace.txt file where you will have the output of the messages. You can check it while the gst is still running
If you are done just break it via ctrl+c
Explaining:
-a --smalltalk-args Pass the remaining arguments to Smalltalk.
Allows you to type in the messages and get the output redirected.
Edit: (missed that question about classes at Namespace)
That being said I'm not big fan of GNU Smalltalk as I don't like the CLI only interface in supports. I think the biggest advantage of Smalltalk from the beginning was its GUI support and if you need it you can use CLI if the Smalltalk environment you are using is supporting it like Smalltalk/X-jv.
Usually inspect is the keyword used in Smalltalk instead of examine. Which will give you an internal view of an object.
If you want to list classes at Namespace you could do it the following way:
NetClients do: [ :namespaceDetail |
namespaceDetail isClass ifTrue: [ namespaceDetail printNl ]
].
To print description of the classes you could to it like this:
NetClients do: [ :namespaceDetail |
namespaceDetail isClass ifTrue: [
'--->' printNl. namespaceDetail printNl. '<---' printNl.
namespaceDetail comment printNl
]
].
In similar fashion you would get selectors.

How to run a program with parameters (Pick BASIC)

In Pick BASIC source code I see lines such as
CALL SOMEPROGRAM (PARAM1, PARAM2)
How can I invoke that same line from the TCL command prompt? I've tried variations of the following but nothing seems to work.
SOMEPROGRAM ('1','2')
The only way I've found is to write and compile a program with the single line command and then run that program.
If this was your routine:
SUBROUTINE REALPROG(A,B)
PRINT "A is ":A
PRINT "B is ":B
END
To call it from command line, you'd build this routine:
PROGRAM WRAPPERPROG
COMMAND.RECEIVED = SENTENCE()
VAR1 = FIELD(COMMAND.RECEIVED,' ',2)
VAR2 = FIELD(COMMAND.RECEIVED,' ',3)
CALL REALPROG(VAR1, VAR2)
END
Assuming you typed this from the TCL/ECL command line:
WRAPPERPROG DOG CAT
VAR1 would be DOG and VAR2 would be CAT
...and would call REALPROG with those parameters and you should see
A is DOG
B is CAT
Tcl can invoke your overall program file as a subprocess using exec, but it is up to your program to turn that into a call to the program and processing of correct arguments.
The Tcl code to run the program will probably look something like this:
exec {*}[auto_execok CALLERPROGRAM]
If you were passing the arguments 1 and 2 over, you'd do this:
exec {*}[auto_execok CALLERPROGRAM] 1 2
Again, that does not say how those values get from the command line into the Pick Basic subprogram. You'll need to consult the Pick documentation for how to do that. But I know (and have tested) that Tcl will definitely have correctly provided them…
In Pick BASIC CALL statements are used to call subroutines and they can't be directly executed from TCL. Subroutines are denoted by setting the first word on the first line of the program to SUBROUTINE.
You can execute "programs" from TCL. These don't include the SUBROUTINE at the top of the source code. In some Pick BASIC variants you may need to include PROGRAM but I think most don't require that (I know D3 doesn't). These programs can be run from TCL but they don't get the command line parameters passed in automatically like subroutines do. I think you can use SENTENCE() in pretty much any Pick BASIC variant to get the command line parameters.
Here's an example program that will print the command line arguments:
PRINT SENTENCE()
END
You could use this to create a program that will take the command line arguments and pass them into a subroutine to do something for you.
I was literally typing out some elaborate answer, but your question has been answered. You cant directly call a subroutine, you need to call a program that calls the subroutine. Also subroutines are a good way to separate code from the main program to reduce clutter, but they arent always necessary. Other methods you can use are functions, or GOSUBS/GOTOS. This is an example of a GOTO below..
VAR = 'HELLO'
GOTO 10:
10:
CRT VAR
from the TCL you will call the name of your program and all of this code will be executed without calling another program.
The output will be the string hello.
I wrote a utility 30+ years ago to address this. Other Basics (QB, VB, Dartmouth) have a single command line. You are either writing lines into a program or processing single line requests. Pick did not.
I created an MD item called PRINT. It then runs a program called BP PRINT that takes the whole TCLREAD line, writes it out to another program space called BP PPRINT, compiles it and then runs it.
Incredibly useful. Thus at TCL these commands would work:
PRINT ; X=1 ; Y=2 ; CALL SOMESUB(X,Y)
PRINT ; FOR I=1 TO 12 ; PRINT (I*28)"DMA" ; NEXT I
PRINT ; OPEN "CUST" THEN READV NAME FROM "1234", 1 THEN PRINT NAME
PRINT OCONV("12345678","MD2Z,$")
PRINT DATE()
Basically anything that can be programmed within a single line of code can be typed at TCL this way. Any IF or ELSE statements must be completed in the same one line. Great for testing.
Should be part of every Pick implementation out of the box.
Mark Johnson

Julia passing arguments, reading the command line

I am trying to prompt the user of my .jl file to enter user entered multiple destinations.
Basically I need the user to give an input & an output. I know in java you would use a scanner, or accept arguments when it is compiled in the command line. I am fine with either option. From what I have found looking through the Julia Documentation I think I could accomplish the first way of assigning a variable to the readline function.
(String)in = (String)Readline(STDIN)
From my understanding the variable 'in' should now contain a String of the user's input. I am encountering an error, in that when I compile my .jl code, because my command prompt does not stop to read user input, and just finishes reading the .jl code.
The first item to note in the code in your question is:
(String)in = (String)Readline(STDIN)
Julia 1.0.0 now uses stdin instead of STDIN.
Next, the (String) typecasting is not something you need or want to do in Julia.
Thus your code could read (though we get an error):
julia> in = readline(stdin)
This is a test.
ERROR: cannot assign variable Base.in from module Main
So variable in is in conflict with a Julia Base.in variable. Just use a another variable name.
julia> response = readline(stdin)
This is a test.
"This is a test"
This code is now working, but it has no prompt. Your answer provides an example input function with a prompt which you defined like this:
julia> function input(prompt::AbstractString="")
print(prompt)
return chomp(readline())
end
input (generic function with 2 methods)
The chomp function removes a single trailing \n newline character from the input string. Docs here.
Example use of the function here:
julia> input_file = input("Please enter input file name: ")
Please enter input file name: Data.txt
"Data.txt"
julia> output_file = input("Please enter output file name: ")
Please enter output file name: Output.txt
"Output.txt"
Command Line Args Method
As the docs point out, to just print out the arguments given to a script, you can do something like this:
println("Arguments passed to ", PROGRAM_FILE, ":")
for arg in ARGS
println(arg)
end
Here is an example of above code running on the Windows command line:
c:\OS_Prompt>julia PrintArgs.jl Data.txt Output1.txt Output2.txt Output3.txt
Arguments passed to PrintArgs.jl:
Data.txt
Output1.txt
Output2.txt
Output3.txt
You can also print out the script file name as shown, PrintArgs.jl.
After searching & testing I found one solution and decided to reply to it here. I had to declare my own function to be able to get the program to accept user input.
function input(prompt::AbstractString="")
print(prompt)
return chomp(readline())
end
I am not sure what the chomp function does, but I know it works for what I was asking. I am still curious if you can do something in Julia similar to java and C String args[], in which you pass extra information while you are telling your command to run. Something like the following.
Julia testFile.jl goHere.txt lookHere.txt

Trying to read in a .gda file to IDL

I am trying to read in a .gda file into IDL for plotting purposes. I am not familiar with the format and my research indicates it is an unformatted binary data file type. Anyways, here is what I am doing:
pro omidi_contour
openr, 1, 'data.gda'
a = fltarr(128,128,128)
readu, 1, a
close, 1
end
However when I look at the variable definition at the left panel of IDL, it indicates that a is 'undefined'. When I try to print:
print, a[0,0,0]
I get:
Variable is undefined: A
How can I solve this?
I found out that there was nothing wrong with my program. It was reading the right values from the file. However, the IDL "forgot" the value of the variables once the program was done. Solution: DO not run this as a program i.e. remove the following lines:
pro omidi_contour
end
This makes the code to run as if each line were typed into the IDL prompt and IDL does remember the values this time round.

How to have excatly the same effect as using "run..." from StartMenu to call a program with command line arguments in C++/CLI?

in a C++/CLI program I'm using
System::Diagnostics::Process::Start("D:\\users\\Z\\project1\\Sent_0.93\\plotCon\\tester\\bin\\Debug\\tester.exe","20 D:\users\Z\project1\Bright20");
to call the tester.exe, which is another project written in C# (but I think it doesn't matter here)
then something strange happens now. If I debug the C# program with command line arguments given in project setting, it's working as expected. If I call this C# program from Start menu->run, it's also working fine.
but with the given line above, the C# program is started, but behaves quite wierd.
So the question is why and how to change the C++ code to make its calling have exactly the same effect as I call from "Start->run"
Thank you
The problem is your string for the arguments parameter -- "20 D:\users\Z\project1\Bright20" has embedded escape characters, you need to use double-backslash as you correctly did for the fileName parameter:
System::Diagnostics::Process::Start(
"D:\\users\\Z\\project1\\Sent_0.93\\plotCon\\tester\\bin\\Debug\\tester.exe",
"20 D:\\users\\Z\\project1\\Bright20"
); // ^^ ^^ ^^ ^^