walkback - seaside decorator isNil at startup - seaside

I'm working my way to become more familiar with seaside on dolphin. I have successfully completed the todo app. Now I have started my own app using the todo app as a guide.
I am getting walkback (see below) in the session start. I have set my app up similar to the todo. One thing I do notice is that when I go back into seaside config the root class says "a JCBYCBi..." rather than "JCBYCBi...", which seems to say an INSTANCE is in config rather than a CLASS.
Any help welcome,
John
decoration
^ decoration contents <== decoration isNil
addDecoration: aDecoration
"Add aDecoration to the receivers decoration chain. Answer the added decoration."
| previous current |
previous := nil.
current := self decoration.
[ current ~~ self and: [ self decoration: current shouldWrap: aDecoration ] ] whileTrue: [
previous := current.
current := current next ].
aDecoration setNext: current.
previous isNil
ifTrue: [ self decoration: aDecoration ]
ifFalse: [ previous setNext: aDecoration ].
^ aDecoration
createRoot
^ self rootDecorationClasses
inject: self rootClass new
into: [ :component :decorationClass |
component
addDecoration: decorationClass new;
yourself ]

Related

Pharo promises:

I worked on a promises project earlier this year in Pharo Smalltalk.
The idea was to achieve the behavior below:
([ 30 seconds wait. 4 ]promiseValue )then: [ :a| Transcript crShow: a ].
This means that the promise will wait in the background for 30 seconds and print on the Transcript. This should not result in freezing of the Pharo user interface.
My implementation below freezes the user interface. Why?
Class promise that implements Promises behavior:
Object subclass: #Promise
instanceVariableNames: 'promiseValue promiseError promiseLock'
classVariableNames: ''
package: 'META-Project-[pgakuo]'
Methods inside class Promise
doesNotUnderstand: aMessage
^ self value
perform: aMessage selector
withArguments: aMessage arguments
then: aBlock
promiseLock isSignaled
ifTrue: [ ^ self ].
promiseLock wait.
promiseError
ifNotNil: [ promiseError
privHandlerContext: thisContext;
signal ].
aBlock value: promiseValue.
self value: aBlock
then: aBlock catch: anotherBlock
promiseLock isSignaled
ifFalse:
[ promiseLock wait.
promiseError ifNotNil: [ anotherBlock value: promiseError ].
promiseValue ifNotNil: [ aBlock value: promiseValue. self value: aBlock ]]
value
promiseLock isSignaled ifFalse: [ promiseLock wait ].
promiseError ifNotNil:
[ promiseError
privHandlerContext: thisContext;
signal ].
^promiseValue
value: aBlock
promiseLock := Semaphore new.
[
[[promiseValue := aBlock value]
on: Error do: [:err | promiseError := err]]
ensure: [promiseLock signal]] fork
And one method added to Blockclosure to make closures use the Promise behavior.
promiseValue
^ Promise new value: self
A block is passed to an instance of Promise and it is executed by Promise>>value: which uses fork to perform tasks in the background. But it does not seem to be working as desired
When working in a playground you'll be working within the UI process. Hence, you are effectively suspending the UI process with your example. Try this:
[ ([ 30 seconds wait. 4 ] promiseValue) then: [ :a |
Transcript crShow: a ] ] forkAt: Processor userBackgroundPriority.
Edit
As the there's the explicit requirement for the original expression to not lock the UI, what you should do is:
do not override #doesNotUnderstand:
you have a choice:
always fork when evaluating a promise
This will incur an overhead due to process scheduling and process creation. You will also lose the context of the original process, unless you explicitly save it (costs memory, incurs performance penalty)
only fork if the current process is the UI process
Checking whether the current process is the UI process is simple and fast. It's not something you would typically do but for your case I'd recommend this approach.
I recommend implementing a class side method for Promise, e.g. Promise class>>value:. This will allow you to isolate this specific case from the rest of your implementation. e.g.
value: aBlock
| instance |
instance := self new.
self isUIProcess
ifTrue: [ [ instance value: aBlock ] forkAt: Processor userBackgroundPriority ]
ifFalse: [ instance value: aBlock ].
^ instance
I solved the freezing problem as follows:
then: aBlock
promiseLock isSignaled
ifFalse:
[ promiseLock wait.
promiseValue ifNotNil: [ aBlock value: promiseValue ]] fork.
And the below code on playground does not freeze the UI
[ 12 seconds wait. 12 ]promiseValue then: [ :a| Transcript crShow: a/2 ]
it prints 6 after 12 seconds of not freezing the UI

YML syntax error

I want to have a multi-line bit of markdown java in a yam file. I tried many things but I guess I don't quite get the quoting rules of Yaml.
{
title: Museum,
body: |
"```java
code code code
java2",
answers: [
"`museum`",
"`museum.getFloor(3)`",
"`museum.getFloor(3).getExhibit(5)`",
"`museum.getFloor(3).getExhibit(5).getCurator()`",
"`museum.getFloor(3).getExhibit(5).getCurator().name`",
"`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`"
]
}
Produces:
/Users/pitosalas/.rbenv/versions/2.3.1/lib/ruby/2.3.0/psych.rb:377:in `parse': (generator/test.yml): found character that cannot start any token while scanning for the next token at line 3 column 9 (Psych::SyntaxError)
YAML has two styles: the JSON like flow style and the much better human readable block style.
Roughly speaking you can have nested structures each style nested within itself and can have flow style nested within block style, but block style nested within flow style is not allowed.
Your to level { and } are flow style but you try to introduce, with |, a literal block style scalar within that flow style. Replace the flow style with block style upwards from that scalar:
title: Museum
body: |
"```java
code code code
java2"
answers: [
"`museum`",
"`museum.getFloor(3)`",
"`museum.getFloor(3).getExhibit(5)`",
"`museum.getFloor(3).getExhibit(5).getCurator()`",
"`museum.getFloor(3).getExhibit(5).getCurator().name`",
"`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`"
]
and your YAML is fine. Note that the double quotes "around" the value for the key body are not going to be stripped when loading, maybe that is not what you intended.
You should IMO not leave out the trailing , after the last value in the (flow style) sequence that is the value for answers. This will certainly lead to errors when you extend the list and forget to put in the trailing comma on the line above.
I would personally go for block style all the way:
title: Museum
body: |
"```java
code code code
java2"
answers:
- "`museum`"
- "`museum.getFloor(3)`"
- "`museum.getFloor(3).getExhibit(5)`"
- "`museum.getFloor(3).getExhibit(5).getCurator()`"
- "`museum.getFloor(3).getExhibit(5).getCurator().name`"
- "`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`"
When dealing with YAML file generation that is convoluted or complex, or when it's not working as I expect, I revert to letting Ruby show me the way:
require 'yaml'
body = <<EOT
"```java
code code code
java2
"
EOT
answers = %w(
`museum`
`museum.getFloor(3)`
`museum.getFloor(3).getExhibit(5)`
`museum.getFloor(3).getExhibit(5).getCurator()`
`museum.getFloor(3).getExhibit(5).getCurator().name`
`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`
)
obj = {
"title" => "Museum",
"body" => body,
"answers" => answers
}
puts obj.to_yaml
Which, in this case, outputs:
---
title: Museum
body: |
"```java
code code code
java2
"
answers:
- "`museum`"
- "`museum.getFloor(3)`"
- "`museum.getFloor(3).getExhibit(5)`"
- "`museum.getFloor(3).getExhibit(5).getCurator()`"
- "`museum.getFloor(3).getExhibit(5).getCurator().name`"
- "`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`"
If you then pass that YAML back into the parser, you should get the original data structure back:
YAML.load(obj.to_yaml)
# => {"title"=>"Museum",
# "body"=>"\"```java\n" +
# "code code code\n" +
# "java2\n" +
# "\"\n",
# "answers"=>
# ["`museum`",
# "`museum.getFloor(3)`",
# "`museum.getFloor(3).getExhibit(5)`",
# "`museum.getFloor(3).getExhibit(5).getCurator()`",
# "`museum.getFloor(3).getExhibit(5).getCurator().name`",
# "`museum.getFloor(3).getExhibit(5).getCurator().name.toUpper()`"]}

ExecJS: keeping the context between two calls

I'm currently trying to use ExecJS to run Handlebars for one of the product I work on (note: I know the handlebars.rb gem which is really cool and I used it for some times but there is issues to get it installed on Windows, so I try another homemade solution).
One of the problem I'm having is that the Javascript context is not kept between each "call" to ExecJS.
Here the code where I instantiate the #js attribute:
class Context
attr_reader :js, :partials, :helpers
def initialize
src = File.open(::Handlebars::Source.bundled_path, 'r').read
#js = ExecJS.compile(src)
end
end
And here's a test showing the issue:
let(:ctx) { Hiptest::Handlebars::Context.new }
it "does not keep context properly (or I'm using the tool wrong" do
ctx.js.eval('my_variable = 42')
expect(ctx.js.eval('my_variable')).to eq(42)
end
And now when I run it:
rspec spec/handlebars_spec.rb:10 1 ↵
I, [2015-02-21T16:57:30.485774 #35939] INFO -- : Not reporting to Code Climate because ENV['CODECLIMATE_REPO_TOKEN'] is not set.
Run options: include {:locations=>{"./spec/handlebars_spec.rb"=>[10]}}
F
Failures:
1) Hiptest::Handlebars Context does not keep context properly (or I'm using the tool wrong
Failure/Error: expect(ctx.js.eval('my_variable')).to eq(42)
ExecJS::ProgramError:
ReferenceError: Can't find variable: my_variable
Note: I got the same issue with "exec" instead of "eval".
That is a silly example. What I really want to do it to run "Handlebars.registerPartial" and later on "Handlebars.compile". But when trying to use the partials in the template it fails because the one registered previously is lost.
Note that I've found a workaround but I find it pretty ugly :/
def register_partial(name, content)
#partials[name] = content
end
def call(*args)
#context.js.call([
"(function (partials, helpers, tmpl, args) {",
" Object.keys(partials).forEach(function (key) {",
" Handlebars.registerPartial(key, partials[key]);",
" })",
" return Handlebars.compile(tmpl).apply(null, args);",
"})"].join("\n"), #partials, #template, args)
end
Any idea on how to fix the issue ?
Only the context you create when you call ExecJS.compile is preserved between evals. Anything you want preserved needs to be part of the initial compile.

How to make "todo" in markdown in sublime text?

I am migrating to sublime text with markdownediting from emacs orgmode. With the help of markdownediting, sublime is fine with markdown. But I haven't figure out how to make TODO list, and toggle between TODO and DONE. Is there a way to do it? or any plugin works well with markdownediting?
I installed the mdTodo plugin for Sublime text.
It works but the TODO list displayed as bulletin list (in html) on GitHub, which looks not so good.
I found that GitHub supports the orgmode-style TODO list:
https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments
https://github.com/blog/1825-task-lists-in-all-markdown-documents
Solar System Exploration, 1950s – 1960s
[ ] Mercury
[x] Venus
[x] Earth (Orbit/Moon)
[x] Mars
[ ] Jupiter
[ ] Saturn
[ ] Uranus
[ ] Neptune
[ ] Comet Haley
So I modified the mdTodo source code, makes it works on orgmode-style TODO list.
Here is my modification: (mdTodo.py in the package folder)
import sublime, sublime_plugin
from datetime import datetime
class ItodoBase(sublime_plugin.TextCommand):
def run(self, edit):
filename = self.view.file_name()
# list of allowed filetypes
allowed_filetypes = ('.md', '.markdown', '.mdown')
if filename is None or not filename.endswith(allowed_filetypes):
return False
self.runCommand(edit)
class NewCommand(ItodoBase):
def runCommand(self, edit):
for region in self.view.sel():
lines = self.view.lines(region)
lines.reverse()
for line in lines:
# don't add a newline when creating new item with cursor is at an empty line
if not line:
line_contents = '-'
self.view.insert(edit, line.begin(), line_contents)
# add a newline when creating new item when cursor is at another line
else:
line_contents = self.view.substr(line) + '\n-'
self.view.replace(edit, line, line_contents)
class CompleteCommand(ItodoBase):
def runCommand(self, edit):
for region in self.view.sel():
lines = self.view.lines(region)
lines.reverse()
for line in lines:
line_head = self.view.find("- \[[x ]\]", line.begin())
line_contents = self.view.substr(line).strip()
# prepend #done if item is ongoing
if line_contents.startswith("- [ ]"):
self.view.insert(edit, line.end(), " #done (%s)" % datetime.now().strftime("%Y-%m-%d %H:%M"))
self.view.replace(edit, line_head, "- [x]")
# undo #todo
elif line_contents.startswith('- [x]'):
subfix = self.view.find('(\s)*#done(.)+\)$', line.begin())
self.view.erase(edit, subfix)
self.view.replace(edit, line_head, "- [ ]")
I hope this would be helpful to those migrated to Sublime text from Emacs (org-mode).
Update
The default shortcut ctrl+shift+d conflicts with the default duplicate line command.
Solution:
path_to_sublime\Sublime Text 3\Packages\mdTodo\Default (Windows).sublime-keymap
Comment out this line
[ // iTodo plugin
{ "keys": ["ctrl+shift+d"], "command": "complete" }
]
and change it in the user keybinds file.
I binded it to:
{ "keys": ["ctrl+alt+d"], "command": "complete" }

Preventing the Jasmine spy to listen improper messages

How can I tell the Jasmine spy to only listen the messages I tell it to expect and ignore any others?
For example:
Example Group
describe 'View', ->
describe 'render', ->
beforeEach ->
#view = new View
#view.el = jasmine.createSpyObj 'el', ['append']
#view.render()
it 'appends the first entry to the list', ->
expect(#view.el.append).toHaveBeenCalledWith '<li>First</li>'
it 'appends the second entry to the list', ->
expect(#view.el.append).toHaveBeenCalledWith '<li>Second</li>'
Implementation
class View
render: ->
#el.append '<li>First</li>', '<li>Second</li>'
Output
View
render
appends the first entry to the list
Expected spy el.append to have been called \
with [ '<li>First</li>' ] but was called \
with [ [ '<li>First</li>', '<li>Second</li>' ] ]
appends the second entry to the list
Expected spy el.append to have been called \
with [ '<li>Second</li>' ] but was called \
with [ [ '<li>First</li>', '<li>Second</li>' ] ]
There are two options:
1. Using the argsForCall spy property
it 'appends the first entry to the list', ->
expect(#view.el.append.argsForCall[0]).toContain '<li>First</li>'
2. Using the args property of the mostRecentCall object
it 'appends the first entry to the list', ->
expect(#view.el.append.mostRecentCall.args).toContain '<li>First</li>'
To be clear, you can't prevent the spy from listening. The spy will listen to all function calls and save them. But you can excess every single call by using argsForCall.

Resources