I'm trying to create an application using Seaside in GNU Smalltalk. I'm running GNU Smalltalk 3.2.5 under Linux (Fedora 17).
I have run and executed the simple counter test app just fine. In my application I need to dynamically create some classes and use them. However, gst-remote won't recognize them. Here's my test application (contents of test.st):
Seaside.WAComponent subclass: Test [
| foo |
Test class >> canBeRoot [ ^true ]
initialize [
super initialize.
Object subclass: #Foo instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'test class'.
foo := Foo new.
]
states [ ^{ self } ]
renderContentOn: html [
html heading: 'Foo'.
]
]
Test registerAsApplication: 'test'
On the "server" side, I run the remote server:
$ gst-remote -I seaside.im --server --start=Seaside
gst-remote server started.
On the application side (actually on the same PC, just a different terminal window), I run the following with the noted error:
$ gst-remote -f test.st
gst-remote: error at line 330: Undefined variable 'Foo' referenced.
I don't understand why Foo is undefined. From a gst interactive session, it works fine:
st> Object subclass: #Foo instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'test class'.
Foo
st> foo := Foo new.
a Foo
Why doesn't gst-remote allow this?
GST is not really a first-class citizen for Seaside development, so your best bet for getting this working is to do the first steps of Seaside development in a Pharo image, and then exporting that code to GST. You are likely to run into some issue where changes have been made to Seaside since 2011. Once your understanding of Seaside (in Pharo) is better, it will likely not be too much work to port to GST. If you do the exporting to GST in a CI setup, we'll be able to help you with concrete questions on the Seaside or Seaside-dev mailing lists.
Related
I am trying to use smalltalk with smalltalk/x-jv branch. I have following simple code:
Object subclass: Myclass[
|mainval|
init [mainval := 555]
getmainval [^mainval]
]
gc := Myclass new.
gc init.
gc getmainval printNl.
I am trying to run it on command line with stc command of smalltalk/x-jv, but it it not working. Following is the error:
$ ./stc testsrc.st
testsrc.st, line 1: Error: syntax error in 'class definition' near "Myclass" (char/token=286 / 0x11e) (fileIn expression)
Where is the problem and how can it be solved? Thanks for your help.
Edit - Adding information about stc and stx
I'm afraid you can't use the GNU Smalltalk code directly within Smalltalk/X(-jv branch). Also it would be nice to see what is your final goal during the Smalltalk question series.
What is important for you to understand that Smalltalk has been designed to work within the IDE if you want to build an application you should use the IDE provided. If you want to build a sample application there is even guide for that for Smalltalk/X. That, of course, do not mean you are unable to start a script from command line (Smalltalk/X is powerfull at shell).
That being said there is a Smalltalk/X highlighting package file for Sublime Text 3 done by myself hosted at BitBucket. I have created it mainly for Smalltalk and its embedded C highlighting.
First you are probably using stx executable and not stc. stc is a shorcut for smalltalk-to-C compiler. stc produces a C code which can then be compiled by a C compiler into an object file which then can be linked with a final executable (together with other smalltalk classes and runtime).
smalltalk or stx is a launcher that can execute smalltalk scripts or open a full-blown IDE. If you're familiar with Java, think of stc as of javac and smalltalk or stx as of java.
You can use the launcher provided called smalltalk (a bash script for *nix and batch/powershell for windows), which is using the stx.com at the end, but providing some additional functionality.
Use smalltalk --help the see the commandline options.
First I will start with a simple one-liner which you can use:
stx.com -I --quick --eval "Transcript showCR: 'A message on stdout on Transcript'
A message on stdout on Transcript
on windows you if you use smalltalk you get more information:
smalltalk -I --quick --eval "Transcript showCR: 'A message on stdout on Transcript'
"[INFO] PowerShell detected: ->TRUE<-.
"[INFO] The latest latest_powershell_version found: 5.1.16299.1004."
"[INFO] With the runtime being: v4.0.30319."
VERBOSE: [INFO] Manual switch detected - configuration is ignored
VERBOSE: [INFO] Executing asynchronously command: C:\prg_sdk\stx8-jv_swing\build\stx\projects\smalltalk\stx.com -I
--quick --eval "Transcript showCR: 'A message on stdout on Transcript'" | Out-null
VERBOSE: A message on stdout on Transcript
VERBOSE:
VERBOSE: [INFO] Exiting from PowerShell with code 0
VERBOSE: [INFO] End. Exiting correctly.
Now lets move to your scripting question
At the beginning the best way is to create the class in IDE and do a fileOut of it. You will then see the correct structure the .st file should have.
I have create a simple file script.st for you (this is simlilar what you would get on a fileOut from IDE):
"{ NameSpace: Smalltalk }"
Object subclass:#MyClass
instanceVariableNames:'mainValue'
classVariableNames:''
poolDictionaries:''
category:''
!
!MyClass methodsFor:'accessing'!
mainValue
^ mainValue
!
mainValue: newValue
mainValue := newValue
! !
!MyClass methodsFor:'initialization & release'!
initialize
super initialize.
mainValue := 555.
! !
gc := MyClass new.
gc initialize.
Transcript showCR: gc mainValue.
How do you run such a sript?
smalltalk --execute script.st
The output will be: 555
If you want to script without "objects" (well everything is object in Smalltalk, but you don't define a class here) you can do simple transcript.st:
| mainValue |
mainValue := 555.
Transcript showCR: mainValue.
again execute it as: smalltalk --execute transcript.st to get identical result.
In bash shell, if you hit up or down arrows, the shell will show you your previous or next command that you entered, and you can edit those commands to be new shell commands.
In perl6, if you do
my $name = prompt("Enter name: ");
it will print "Enter name: " and then ask for input; is there a way to have perl6 give you a default value and then you just edit the default to be the new value. E.g.:
my $name = prompt("Your name:", "John Doe");
and it prints
Your name: John Doe
where the John Doe part is editable, and when you hit enter, the edited string is the value of $name.
https://docs.raku.org/routine/prompt does not show how to do it.
This is useful if you have to enter many long strings each of which is just a few chars different from others.
Thanks.
To get the editing part going, you could use the Linenoise module:
zef install Linenoise
(https://github.com/hoelzro/p6-linenoise)
Then, in your code, do:
use Linenoise;
sub prompt($p) {
my $l = linenoise $p;
linenoiseHistoryAdd($l);
$l
}
Then you can do your loop with prompt. Remember, basically all Perl 6 builtin functions can be overridden lexically. Now, how to fill in the original string, that I haven't figure out just yet. Perhaps the libreadline docs can help you with that.
Well by default, programs are completely unaware of their terminals.
You need your program to communicate with the terminal to do things like pre-fill an input line, and it's unreasonable to expect Perl 6 to handle something like this as part of the core language.
That said, your exact case is handled by the Readline library as long as you have a compatible terminal.
It doesn't look like the perl 6 Readline has pre-input hooks setup so you need to handle the callback and read loop yourself, unfortunately. Here's my rough attempt that does exactly what you want:
use v6;
use Readline;
sub prompt-prefill($question, $suggestion) {
my $rl = Readline.new;
my $answer;
my sub line-handler( Str $line ) {
rl_callback_handler_remove();
$answer = $line;
}
rl_callback_handler_install( "$question ", &line-handler );
$rl.insert-text($suggestion);
$rl.redisplay;
while (!$answer) {
$rl.callback-read-char();
}
return $answer;
}
my $name = prompt-prefill("What's your name?", "Bob");
say "Hi $name. Go away.";
If you are still set on using Linenoise, you might find the 'hints' feature good enough for your needs (it's used extensively by the redis-cli application if you want a demo). See the hint callback used with linenoiseSetHintsCallback in the linenoise example.c file. If that's not good enough you'll have to start digging into the guts of linenoise.
Another solution :
Use io-prompt
With that you can set a default value and even a default type:
my $a = ask( "Life, the universe and everything?", 42, type => Num );
Life, the universe and everything? [42]
Int $a = 42
You can install it with:
zef install IO::Prompt
However, if just a default value is not enough. Then it is better you use the approach Liz has suggested.
Smalltalk inspect is a powerful tool. Is there any (easy) way to get the information from inspect and show it in Transcript window or write into a file instead of showing it in new window?
I need it because I want to create a kind of debbuger for a program that runs as unix process (not a 'window' program) and logs information into a log file.
Thanks for help!
If you're asking whether something is built in, then I don't think so (although it would help if you tagged the question with which Smalltalk you are using).
Although it would be pretty easy to walk over the inst vars and roll your own (although maybe not for immediate objects), the "easiest" way might be to look at the inspector code and see how it operates. For example, in Pharo 4.0 one could (very basically) leverage the inspector code like so:
i := EyeInspector inspector: 1.
Transcript show: i objectClass; cr.
i elements do: [ :e | Transcript show: e; cr ].
which would print:
SmallInteger
'self'->1
'hex'->1
'octal'->1
'binary'->1
'character'->Character home
In Pharo, you can also get all of the Transcript output going to the console with:
NonInteractiveTranscript stdout install
If you are about debugging, you can have debugger interactions dump things into files (of course, you'll not be able to step in there but it can be useful for headless systems):
NonInteractiveUIManager compile: 'openDebuggerOn: process context: context label: title contents: contentsStringOrNil fullView: bool
| out |
out := VTermOutputDriver stdout.
out
<< ''NonInteractive Debugger: '';
<< title;
cr.
contentsStringOrNil ifNotNil: [ out << contentsStringOrNil; cr ].
(context stackOfSize: 20) do: [:s | out << s printString; cr ].
out << ''------------------------------''; cr; cr.
^ self nonInteractiveWarning: ''Opening Debugger''' classified: #'ui-requests'.
This and Sean's answer should go a long way.
You can get back to normal with the Transcript with:
ThreadSafeTranscript install.
Pharo 3.0 here.
I am posting here after asking the question at the openslice dds forum, and not receiving any reply.I am trying to use opensplice dds on a ubuntu machine. I am not sure if it serves as a proof of proper installation, but I have pasted my release.com file below. Now, I was able to run the ping pong example just fine. But when I ran the executable sac_helloworld_pub ( HelloWorld example in the C programming language), I got the following error
vishal#expmach:~/HDE/x86.linux2.6/examples/dcps/HelloWorld/c/standalone$ ./sac_helloworld_pub
Error in DDS_DomainParticipantFactory_create_participant: Creation failed: invalid handle
I did some searching, and it looks like I need to be running the ospl start command from the terminal. But when I do so, I get a No command ospl found message. Below is the release.comfile's contents
echo "<<< OpenSplice HDE Release V6.3.130716OSS For x86.linux2.6, Date 2013-07-30 >>>"
if [ "${SPLICE_ORB:=}" = "" ]
then
SPLICE_ORB=DDS_OpenFusion_1_6_1
export SPLICE_ORB
fi
if [ "${SPLICE_JDK:=}" = "" ]
then
SPLICE_JDK=jdk
export SPLICE_JDK
fi
OSPL_HOME="/home/vishal/HDE/x86.linux2.6"
OSPL_TARGET=x86.linux2.6
PATH=$OSPL_HOME/bin:$PATH
LD_LIBRARY_PATH=$OSPL_HOME/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
CPATH=$OSPL_HOME/include:$OSPL_HOME/include/sys:${CPATH:=}
OSPL_URI=file://$OSPL_HOME/etc/config/ospl.xml
OSPL_TMPL_PATH=$OSPL_HOME/etc/idlpp
. $OSPL_HOME/etc/java/defs.$SPLICE_JDK
export OSPL_HOME OSPL_TARGET PATH LD_LIBRARY_PATH CPATH OSPL_TMPL_PATH OSPL_URI
$#
release.com (END)
Sorry for the holidays-driven lack of 'reactivity' on the OpenSplice forum .. I've answered your question there though ..
Here's that same answer for completeness:
*For the 6.3 community-edition, the deployment-model changed from shared-memory (v5.x) to the so-called single-process standalone deployment mode where the middleware is simply linked (as libraries) with the application so you don't need to start any daemons first (as was the case for the federated 'shared-memory' mode that was the default in V5).
So its OK that you get the error when trying to call 'ospl' as thats not used anymore so isn't in the distribution.
Now to your issue, your release.com looks OK to me, but perhaps you didn't actually 'source' it in your environment i.e. calling it with a '.' in front of it:
promtp> . release.com
you can verify that by doing an 'echo $OSPL_HOME' in your shell and see if it actually shows the value of the env. variable as set by the release.com.
Hope that helps,
-Hans*
Can I launch Squeak as a REPL (no GUI), where I can enter and evaluate Smalltalk expressions? I know the default image don't allow this. Is there any documentation on how to build a minimum image that can be accessed from a command-line shell?
Here is a (hackish) solution:
First, you need OSProcess, so run this in a Workspace:
Gofer new squeaksource:'OSProcess'; package:'OSProcess';load.
Next, put this in the file repl.st:
OSProcess thisOSProcess stdOut
nextPutAll: 'Welcome to the simple Smalltalk REPL';
nextPut: Character lf; nextPut: $>; flush.
[ |input|
[ input := OSProcess readFromStdIn.
input size > 0 ifTrue: [
OSProcess thisOSProcess stdOut
nextPutAll: ((Compiler evaluate: input) asString;
nextPut: Character lf; nextPut: $>; flush
]
] repeat.
]forkAt: (Processor userBackgroundPriority)
And last, run this command:
squeak -headless path/to/squeak.image /absolute/path/to/repl.st
You can now have fun with a Smalltalk REPL. Dont forget to type in the command:
Smalltalk snapshot:true andQuit:true
if you want to save your changes.
Now, onto the explanation of this solution:
OSProcess is a package that allows to run other processes, read from stdin, and write to stdout and stderr. You can access the stdout AttachableFileStream with OSProcess thisOSProcess (the current process, aka squeak).
Next, you run an infinite loop at userBackgroundPriority (to let other processes run). In this infinite loop, you use Compiler evaluate: to execute the input.
And you run this in a script with a headless image.
As of Pharo 2.0 (and 1.3/1.4 with the fix described below), there are no more hacks necessary. The following snippet will turn your vanilla Pharo image into a REPL server...
From https://gist.github.com/2604215:
"Works out of the box in Pharo 2.0. For prior versions (definitely works in 1.3 and 1.4), first file in https://gist.github.com/2602113"
| command |
[
command := FileStream stdin nextLine.
command ~= 'exit' ] whileTrue: [ | result |
result := Compiler evaluate: command.
FileStream stdout nextPutAll: result asString; lf ].
Smalltalk snapshot: false andQuit: true.
If you want the image to always be a REPL, put the code in a #startup: method; otherwise, pass the script at the command line when you want REPL mode, like:
"/path/to/vm" -headless "/path/to/Pharo-2.0.image" "/path/to/gistfile1.st"
Please visit:
http://map.squeak.org/package/2c3b916b-75e2-455b-b25d-eba1bbc94b84
and Run Smalltalk on server without GUI?
The project http://www.squeaksource.com/SecureSqueak.html includes a REPL package that may provide much of what you are looking for.