├── .gitignore ├── PharoProjects ├── Metalinks.md ├── WebBrowser.md ├── ObjectsSerialization.md ├── Cursor.md ├── OS.md ├── Numbers.md ├── DynamicVariables.md ├── RichText.md └── Announcer.md ├── ExternalProjects ├── DataStructures │ └── DataFrame.md └── Export │ ├── XML.md │ ├── HTML.md │ ├── Arff.md │ ├── ESCP.md │ ├── CSV.md │ └── JSON.md ├── General ├── Files.md ├── win_2.png ├── win_3.png ├── win_4.png ├── GithubActions_os.png ├── Playground_do_it.png ├── Inspector_meta_tab.png ├── Inspector_raw_tab.png ├── Playground_debug_it.png ├── Playground_overview.png ├── Playground_print_it.png ├── Playground_settings.png ├── SettingUp_TestClass.png ├── GithubActions_matrix.png ├── Inspector_breakpoints.gif ├── Playground_print_sum.png ├── Profiling_Image_Bench.png ├── SettingUp_AddingClass.png ├── SettingUp_AddingInit.png ├── SettingUp_NewPackage.png ├── SettingUp_NewProtocol.png ├── SettingUp_NewRepoGit.png ├── Settings_Image_Parent.png ├── GitHubActions_workflows.png ├── GithubActions_continuous.png ├── GithubActions_coveralls.png ├── GithubActions_releases.png ├── Inspector_expension_max.png ├── Inspector_numbers_tabs.png ├── Inspector_pane_toolbar.png ├── Inspector_raw_tab_areas.png ├── Playground_do_it_and_go.png ├── Playground_print_result.png ├── SettingUp_AddingVariable.png ├── SettingUp_CreateNewRepo.png ├── SettingUp_DownloadPharo.png ├── SettingUp_PharoLauncher.png ├── SettingUp_SystemBrowser.png ├── Settings_Image_MySetting.png ├── CJKCharacter_Screenshot_1.png ├── CJKCharacter_Screenshot_2.png ├── Inspector_pane_navigation.gif ├── Playground_open_from_image.png ├── Playground_with_only_text.png ├── Profiling_Image_SpaceTally.png ├── SettingUp_AddingGetAndSet.png ├── SettingUp_DecrementMethod.png ├── SettingUp_FirstTestObject.png ├── SettingUp_IncrementMethod.png ├── Inspector_expension_histogram.png ├── SettingUp_SecondTestIncrement.png ├── SettingUp_ThirdTestDecrement.png ├── Settings_Image_RangeSetting.png ├── Playground_inspect_on_Time_now.png ├── Settings_Image_LaunchingAScript.png ├── Settings_Image_SettingsBrowser.png ├── Exceptions_Image_ExampleDebugger.png ├── Exceptions_Image_ExceptionSample.png ├── Exceptions_Image_InformationPopUp.png ├── Inspector_expension_first_element.png ├── Profiling_Image_TimeProfilerToolUI.png ├── Settings_Image_MySettingGroupNode.png ├── Settings_Image_OpenSettingsBrowser.png ├── Exceptions_Image_ExamplePreDebugger.png ├── Extensions_Image_CalypsoAddExtension.png ├── Profiling_Image_TimeProfilerMenuItem.png ├── Settings_Image_ListOfPossibleValues.png ├── Settings_Image_MySettingSettingNode.png ├── Baselines_Image_LoadBaselineViaIceberg.png ├── Extensions_Image_CalypsoSeeExtensions.png ├── Extensions_Image_NautilusAddExtension1.png ├── Extensions_Image_NautilusAddExtension2.png ├── Extensions_Image_NautilusSeeExtensions.png ├── Inspector_expension_multiplied_by_two.png ├── MenuBar_Image_WhatIsMenuBarAndWorldMenu.png ├── Settings_Image_NestedDeclarationsResult.png ├── Inspector_expension_max_without_evaluator.png ├── Profiling_Image_TimeProfilerFromCommandLine.png ├── layout_screenshot │ ├── RowLayoutExampleWithTwoMorph.png │ ├── RowLayoutExampleWithThreeMorph.png │ ├── TableLayoutExampleWithTwoMorph.png │ ├── ProportionnalLayoutWithScrollBar.png │ ├── TableLayoutExampleWithThreeMorph.png │ ├── ProportionnalLayoutWithLeftTop50perY.png │ ├── TableLayoutWithWrapCenteringCenter.png │ ├── TableLayoutWithWrapCenteringtopLeft.png │ ├── TableLayoutWithWrapCenteringbottomRight.png │ ├── ProportionnalLayoutWithLeftTop50perX50perY.png │ ├── RowLayoutExampleWithTwoMorphCellPositionCenter.png │ ├── RowLayoutwithvResizingAndhResizingAtshrinkWrap.png │ ├── TableLayoutExampleWithTwoMorphWithTopLeftMorph.png │ ├── RowLayoutExampleWithTwoMorphCellPositionTopLeft.png │ ├── TableLayoutExampleWithTwoMorphWithCenteringMorph.png │ ├── TableLayoutExampleWithTwoMorphWithTopRightMorph.png │ ├── TableLayoutWithVResizingAndhResizingAsSpacefill.png │ ├── RowLayoutExampleWithTwoMorphCellPositionBottomLeft.png │ ├── StackLayoutExampleWithTwoMorphWithLowerMorphExtent.png │ ├── StackLayoutExampleWithTwoMorphWithUpperMorphExtent.png │ ├── TableLayoutWithverticalandHorizontalRigidResizing.png │ ├── StackLayoutExampleWithTwoMorphCellPositioningTopRight.png │ ├── ProportionnalLayoutExampleWithSystemWIndowWithTwoMorph.png │ ├── RowLayoutwithvResizingAndhResizingAtSpacefillForOneMorph.png │ ├── StackLayoutExampleWithTwoMorphCellPositioningBottomRight.png │ ├── TableLayoutWithverticalandHorizontalShrinkwrapResizing.png │ └── ProportionnalLayoutExampleWithSystemWIndowWithFulllWindow.png ├── Exceptions_Image_WhatHappensWhenAnExceptionIsSignalled.png ├── Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment2_retry.png ├── Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment4_outer.png ├── Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment1_return.png ├── Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment3_resume.png ├── CJKInputMethod.md ├── HowToRunPharoFromCommandLine.md ├── Windows10SubsystemForLinux.md ├── ImageFileFormat.md ├── Travis.md ├── CodingConventions.md ├── ProgressBar.md ├── CJKCharacter.md ├── Profiling.md ├── IcebergOnWindows.md ├── Extensions.md ├── MustKnowForBeginners.md ├── MenuBar.md ├── SortingCollections.md ├── SessionsManagement.md ├── InterestingsToKnowForBeginners.md ├── CoolSnippets.md ├── TweakingBigImages.md ├── Pragmas.md ├── ExportFormats.md ├── Inspector.md ├── Traits.md ├── Playground.md ├── Exceptions.md └── SettingUpANewProject.md ├── Resources ├── EditPage.gif └── CreatePage.gif ├── .github └── workflows │ └── continuous.yml ├── ExternalResources └── Community.md ├── MANIFEST.md ├── CONTRIBUTION.md ├── Migration └── MigrationToPharo7.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_STORE 2 | -------------------------------------------------------------------------------- /PharoProjects/Metalinks.md: -------------------------------------------------------------------------------- 1 | # Metalinks 2 | 3 | > **TODO** 4 | -------------------------------------------------------------------------------- /ExternalProjects/DataStructures/DataFrame.md: -------------------------------------------------------------------------------- 1 | # DataFrame 2 | 3 | -------------------------------------------------------------------------------- /General/Files.md: -------------------------------------------------------------------------------- 1 | # Files 2 | TODO: explain how to manipulate files, paths, file systems, etc... 3 | -------------------------------------------------------------------------------- /General/win_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/win_2.png -------------------------------------------------------------------------------- /General/win_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/win_3.png -------------------------------------------------------------------------------- /General/win_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/win_4.png -------------------------------------------------------------------------------- /Resources/EditPage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/Resources/EditPage.gif -------------------------------------------------------------------------------- /Resources/CreatePage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/Resources/CreatePage.gif -------------------------------------------------------------------------------- /General/GithubActions_os.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GithubActions_os.png -------------------------------------------------------------------------------- /General/Playground_do_it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_do_it.png -------------------------------------------------------------------------------- /General/Inspector_meta_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_meta_tab.png -------------------------------------------------------------------------------- /General/Inspector_raw_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_raw_tab.png -------------------------------------------------------------------------------- /General/Playground_debug_it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_debug_it.png -------------------------------------------------------------------------------- /General/Playground_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_overview.png -------------------------------------------------------------------------------- /General/Playground_print_it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_print_it.png -------------------------------------------------------------------------------- /General/Playground_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_settings.png -------------------------------------------------------------------------------- /General/SettingUp_TestClass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_TestClass.png -------------------------------------------------------------------------------- /ExternalProjects/Export/XML.md: -------------------------------------------------------------------------------- 1 | # XML support in Pharo 2 | To be done, talk about XML parsers, XML model, XPath implementation, etc... 3 | -------------------------------------------------------------------------------- /General/GithubActions_matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GithubActions_matrix.png -------------------------------------------------------------------------------- /General/Inspector_breakpoints.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_breakpoints.gif -------------------------------------------------------------------------------- /General/Playground_print_sum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_print_sum.png -------------------------------------------------------------------------------- /General/Profiling_Image_Bench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Profiling_Image_Bench.png -------------------------------------------------------------------------------- /General/SettingUp_AddingClass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_AddingClass.png -------------------------------------------------------------------------------- /General/SettingUp_AddingInit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_AddingInit.png -------------------------------------------------------------------------------- /General/SettingUp_NewPackage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_NewPackage.png -------------------------------------------------------------------------------- /General/SettingUp_NewProtocol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_NewProtocol.png -------------------------------------------------------------------------------- /General/SettingUp_NewRepoGit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_NewRepoGit.png -------------------------------------------------------------------------------- /General/Settings_Image_Parent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_Parent.png -------------------------------------------------------------------------------- /General/GitHubActions_workflows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GitHubActions_workflows.png -------------------------------------------------------------------------------- /General/GithubActions_continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GithubActions_continuous.png -------------------------------------------------------------------------------- /General/GithubActions_coveralls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GithubActions_coveralls.png -------------------------------------------------------------------------------- /General/GithubActions_releases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/GithubActions_releases.png -------------------------------------------------------------------------------- /General/Inspector_expension_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_expension_max.png -------------------------------------------------------------------------------- /General/Inspector_numbers_tabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_numbers_tabs.png -------------------------------------------------------------------------------- /General/Inspector_pane_toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_pane_toolbar.png -------------------------------------------------------------------------------- /General/Inspector_raw_tab_areas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_raw_tab_areas.png -------------------------------------------------------------------------------- /General/Playground_do_it_and_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_do_it_and_go.png -------------------------------------------------------------------------------- /General/Playground_print_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_print_result.png -------------------------------------------------------------------------------- /General/SettingUp_AddingVariable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_AddingVariable.png -------------------------------------------------------------------------------- /General/SettingUp_CreateNewRepo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_CreateNewRepo.png -------------------------------------------------------------------------------- /General/SettingUp_DownloadPharo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_DownloadPharo.png -------------------------------------------------------------------------------- /General/SettingUp_PharoLauncher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_PharoLauncher.png -------------------------------------------------------------------------------- /General/SettingUp_SystemBrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_SystemBrowser.png -------------------------------------------------------------------------------- /General/Settings_Image_MySetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_MySetting.png -------------------------------------------------------------------------------- /ExternalProjects/Export/HTML.md: -------------------------------------------------------------------------------- 1 | # HTML support in Pharo 2 | To be done, talk about HTML parser(s) 3 | 4 | - XMLParser-HTML 5 | 6 | - Soup ? 7 | -------------------------------------------------------------------------------- /General/CJKCharacter_Screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/CJKCharacter_Screenshot_1.png -------------------------------------------------------------------------------- /General/CJKCharacter_Screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/CJKCharacter_Screenshot_2.png -------------------------------------------------------------------------------- /General/Inspector_pane_navigation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_pane_navigation.gif -------------------------------------------------------------------------------- /General/Playground_open_from_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_open_from_image.png -------------------------------------------------------------------------------- /General/Playground_with_only_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_with_only_text.png -------------------------------------------------------------------------------- /General/Profiling_Image_SpaceTally.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Profiling_Image_SpaceTally.png -------------------------------------------------------------------------------- /General/SettingUp_AddingGetAndSet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_AddingGetAndSet.png -------------------------------------------------------------------------------- /General/SettingUp_DecrementMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_DecrementMethod.png -------------------------------------------------------------------------------- /General/SettingUp_FirstTestObject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_FirstTestObject.png -------------------------------------------------------------------------------- /General/SettingUp_IncrementMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_IncrementMethod.png -------------------------------------------------------------------------------- /General/Inspector_expension_histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_expension_histogram.png -------------------------------------------------------------------------------- /General/SettingUp_SecondTestIncrement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_SecondTestIncrement.png -------------------------------------------------------------------------------- /General/SettingUp_ThirdTestDecrement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/SettingUp_ThirdTestDecrement.png -------------------------------------------------------------------------------- /General/Settings_Image_RangeSetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_RangeSetting.png -------------------------------------------------------------------------------- /ExternalProjects/Export/Arff.md: -------------------------------------------------------------------------------- 1 | # Arff support in Pharo 2 | To be done, talk about the [Arff parser/generator](https://github.com/juliendelplanque/Arff) 3 | -------------------------------------------------------------------------------- /ExternalProjects/Export/ESCP.md: -------------------------------------------------------------------------------- 1 | # ESCP support in Pharo 2 | To be done, talk about the [ESCP parser/generator](https://github.com/juliendelplanque/ESCP) 3 | -------------------------------------------------------------------------------- /General/Playground_inspect_on_Time_now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Playground_inspect_on_Time_now.png -------------------------------------------------------------------------------- /General/Settings_Image_LaunchingAScript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_LaunchingAScript.png -------------------------------------------------------------------------------- /General/Settings_Image_SettingsBrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_SettingsBrowser.png -------------------------------------------------------------------------------- /General/Exceptions_Image_ExampleDebugger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_ExampleDebugger.png -------------------------------------------------------------------------------- /General/Exceptions_Image_ExceptionSample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_ExceptionSample.png -------------------------------------------------------------------------------- /General/Exceptions_Image_InformationPopUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_InformationPopUp.png -------------------------------------------------------------------------------- /General/Inspector_expension_first_element.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_expension_first_element.png -------------------------------------------------------------------------------- /General/Profiling_Image_TimeProfilerToolUI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Profiling_Image_TimeProfilerToolUI.png -------------------------------------------------------------------------------- /General/Settings_Image_MySettingGroupNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_MySettingGroupNode.png -------------------------------------------------------------------------------- /General/Settings_Image_OpenSettingsBrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_OpenSettingsBrowser.png -------------------------------------------------------------------------------- /General/Exceptions_Image_ExamplePreDebugger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_ExamplePreDebugger.png -------------------------------------------------------------------------------- /General/Extensions_Image_CalypsoAddExtension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Extensions_Image_CalypsoAddExtension.png -------------------------------------------------------------------------------- /General/Profiling_Image_TimeProfilerMenuItem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Profiling_Image_TimeProfilerMenuItem.png -------------------------------------------------------------------------------- /General/Settings_Image_ListOfPossibleValues.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_ListOfPossibleValues.png -------------------------------------------------------------------------------- /General/Settings_Image_MySettingSettingNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_MySettingSettingNode.png -------------------------------------------------------------------------------- /General/Baselines_Image_LoadBaselineViaIceberg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Baselines_Image_LoadBaselineViaIceberg.png -------------------------------------------------------------------------------- /General/Extensions_Image_CalypsoSeeExtensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Extensions_Image_CalypsoSeeExtensions.png -------------------------------------------------------------------------------- /General/Extensions_Image_NautilusAddExtension1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Extensions_Image_NautilusAddExtension1.png -------------------------------------------------------------------------------- /General/Extensions_Image_NautilusAddExtension2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Extensions_Image_NautilusAddExtension2.png -------------------------------------------------------------------------------- /General/Extensions_Image_NautilusSeeExtensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Extensions_Image_NautilusSeeExtensions.png -------------------------------------------------------------------------------- /General/Inspector_expension_multiplied_by_two.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_expension_multiplied_by_two.png -------------------------------------------------------------------------------- /General/MenuBar_Image_WhatIsMenuBarAndWorldMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/MenuBar_Image_WhatIsMenuBarAndWorldMenu.png -------------------------------------------------------------------------------- /General/Settings_Image_NestedDeclarationsResult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Settings_Image_NestedDeclarationsResult.png -------------------------------------------------------------------------------- /General/Inspector_expension_max_without_evaluator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Inspector_expension_max_without_evaluator.png -------------------------------------------------------------------------------- /General/Profiling_Image_TimeProfilerFromCommandLine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Profiling_Image_TimeProfilerFromCommandLine.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutExampleWithTwoMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutExampleWithTwoMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutExampleWithThreeMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutExampleWithThreeMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutExampleWithTwoMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutExampleWithTwoMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/ProportionnalLayoutWithScrollBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/ProportionnalLayoutWithScrollBar.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutExampleWithThreeMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutExampleWithThreeMorph.png -------------------------------------------------------------------------------- /General/Exceptions_Image_WhatHappensWhenAnExceptionIsSignalled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_WhatHappensWhenAnExceptionIsSignalled.png -------------------------------------------------------------------------------- /General/layout_screenshot/ProportionnalLayoutWithLeftTop50perY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/ProportionnalLayoutWithLeftTop50perY.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithWrapCenteringCenter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithWrapCenteringCenter.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithWrapCenteringtopLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithWrapCenteringtopLeft.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithWrapCenteringbottomRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithWrapCenteringbottomRight.png -------------------------------------------------------------------------------- /General/layout_screenshot/ProportionnalLayoutWithLeftTop50perX50perY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/ProportionnalLayoutWithLeftTop50perX50perY.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionCenter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionCenter.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutwithvResizingAndhResizingAtshrinkWrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutwithvResizingAndhResizingAtshrinkWrap.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutExampleWithTwoMorphWithTopLeftMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutExampleWithTwoMorphWithTopLeftMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionTopLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionTopLeft.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutExampleWithTwoMorphWithCenteringMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutExampleWithTwoMorphWithCenteringMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutExampleWithTwoMorphWithTopRightMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutExampleWithTwoMorphWithTopRightMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithVResizingAndhResizingAsSpacefill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithVResizingAndhResizingAsSpacefill.png -------------------------------------------------------------------------------- /General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment2_retry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment2_retry.png -------------------------------------------------------------------------------- /General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment4_outer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment4_outer.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionBottomLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionBottomLeft.png -------------------------------------------------------------------------------- /General/layout_screenshot/StackLayoutExampleWithTwoMorphWithLowerMorphExtent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/StackLayoutExampleWithTwoMorphWithLowerMorphExtent.png -------------------------------------------------------------------------------- /General/layout_screenshot/StackLayoutExampleWithTwoMorphWithUpperMorphExtent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/StackLayoutExampleWithTwoMorphWithUpperMorphExtent.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithverticalandHorizontalRigidResizing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithverticalandHorizontalRigidResizing.png -------------------------------------------------------------------------------- /General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment1_return.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment1_return.png -------------------------------------------------------------------------------- /General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment3_resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment3_resume.png -------------------------------------------------------------------------------- /General/layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningTopRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningTopRight.png -------------------------------------------------------------------------------- /General/layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithTwoMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithTwoMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/RowLayoutwithvResizingAndhResizingAtSpacefillForOneMorph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/RowLayoutwithvResizingAndhResizingAtSpacefillForOneMorph.png -------------------------------------------------------------------------------- /General/layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningBottomRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningBottomRight.png -------------------------------------------------------------------------------- /General/layout_screenshot/TableLayoutWithverticalandHorizontalShrinkwrapResizing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/TableLayoutWithverticalandHorizontalShrinkwrapResizing.png -------------------------------------------------------------------------------- /General/layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithFulllWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pharo-open-documentation/pharo-wiki/HEAD/General/layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithFulllWindow.png -------------------------------------------------------------------------------- /General/CJKInputMethod.md: -------------------------------------------------------------------------------- 1 | # Using CJK (Chinese, Japanese, and Korean) Input Method 2 | 3 | It's possible to use CJK input method in Pharo. Tested under Pharo8 on macOS, Linux and Windows. 4 | 5 | ## Linux 6 | 7 | On linux, you need add `-compositioninput` in VM args and make sure you are using Fcitx5. 8 | -------------------------------------------------------------------------------- /PharoProjects/WebBrowser.md: -------------------------------------------------------------------------------- 1 | # Web browser 2 | 3 | *WebBrowser* is a project included since Pharo 7. The goal of the project is to offer to the user the possibility to open a link directly into the default browser of the computer. 4 | 5 | It currently supports: 6 | - Most linux 32 and 64bits 7 | - OSX 32 and 64bits 8 | - Windows 32bits 9 | 10 | To use it you just need to call: 11 | 12 | ```Smalltalk 13 | WebBrowser openOn: 'https://pharo.org' 14 | ``` 15 | -------------------------------------------------------------------------------- /General/HowToRunPharoFromCommandLine.md: -------------------------------------------------------------------------------- 1 | # Getting Pharo running from the command line 2 | 3 | Here are some simple steps to get Pharo ready from the command line. The script 4 | assumes that you have a bin folder in your home directory. 5 | 6 | The following script downloads the stable vm version of Pharo 80. Check the web page [https://get.pharo.org/64/](https://get.pharo.org/64/) 7 | to get the possible choices. 8 | 9 | ```bash 10 | mkdir bin 11 | cd bin 12 | curl https://get.pharo.org/64/vm80 | bash 13 | ``` 14 | 15 | This script creates two scripts, pharo-ui and pharo-vm both using the contents of the Pharo folder that is also created. 16 | 17 | Once installed you can execute pharo as follows: 18 | 19 | ```bash 20 | ./pharo-ui Pharo8.image 21 | ``` 22 | 23 | If you do not want Pharo displaying a user interface as a pop-up, you can invoke it as follows: 24 | 25 | ```bash 26 | ./pharo Pharo8.image 27 | ``` 28 | -------------------------------------------------------------------------------- /.github/workflows/continuous.yml: -------------------------------------------------------------------------------- 1 | name: Broken links 2 | 3 | env: 4 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 5 | 6 | # Controls when the action will run. Triggers the workflow on push or pull request 7 | # events but only for the development branch 8 | on: 9 | push: 10 | branches: 11 | - 'master' 12 | pull_request: 13 | types: [assigned, opened, synchronize, reopened] 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Defining a new Environment Variable 21 | run: | 22 | TEMPFILES=$(ls **/*.md) 23 | echo "FILES<> $GITHUB_ENV 24 | echo $TEMPFILES >> $GITHUB_ENV 25 | echo "EOF" >> $GITHUB_ENV 26 | - uses: docker://dkhamsing/awesome_bot:latest 27 | with: 28 | args: --white-list travis-ci,127.0.0.1,smalltalkhub.com/mc,github.com/MY_USERNAME/MY_PROJET_NAME --allow 403 --allow-dupe --allow-redirect --skip-save-results ${{ env.FILES }} 29 | -------------------------------------------------------------------------------- /PharoProjects/ObjectsSerialization.md: -------------------------------------------------------------------------------- 1 | # Objects serialization support 2 | To be done. 3 | 4 | ## STON 5 | -> [doc](https://github.com/svenvc/ston/blob/master/ston-paper.md) 6 | 7 | ## Fuel 8 | -> [doc]() 9 | 10 | ## STON v.s. Fuel 11 | 12 | |Property |STON |Fuel | 13 | |----------------------------------------------------|--------------------|--------------------| 14 | |Human-readable | :white_check_mark: | :x: | 15 | |Built-in | :white_check_mark: | :white_check_mark: | 16 | |Works between different major Pharo versions | :white_check_mark: | :x:* | 17 | |Does not require configuration on seralized objects | :x: | :white_check_mark: | 18 | 19 | > *It might work but it is not likely. If a fix was done on Fuel during Pharo development (which is likely), it might make your `.fuel` files unreadable by Pharo. STON is more stable from this perspective. 20 | -------------------------------------------------------------------------------- /PharoProjects/Cursor.md: -------------------------------------------------------------------------------- 1 | # Cursor 2 | 3 | The `Cursor` class in Pharo manages the display of the cursor on the screen. 4 | 5 | It is possible to change the way it looks and we will explain how here. 6 | 7 | To select the cursor you want you can check the class side of the `Cursor` class, in "constants" protocol. 8 | 9 | The common way to change the look of the cursor is to change it for the execution of a block and then set it back to the original cursor. To do that you can use the `showWhile:` method. 10 | 11 | ```Smalltalk 12 | Cursor wait showWhile: [ 3 second wait ] 13 | ``` 14 | 15 | It might be needed to have full control on the cursor without using a block. To do that Morph implements methods to help with the management of cursors via the hand morph. In the following code, `self` can be any object (`#currentHand` is defined on Object). 16 | 17 | ```Smalltalk 18 | self currentHand showTemporaryCursor: Cursor wait. 19 | self flag: #doSomethingHere. 20 | self currentHand showTemporaryCursor: nil. "Reset the cursor to the previous one" 21 | ``` 22 | -------------------------------------------------------------------------------- /General/Windows10SubsystemForLinux.md: -------------------------------------------------------------------------------- 1 | # How to get Pharo running on WSL 2 | 3 | Pharo can be run under Windows 10 Subsystem for Linux (WSL). 4 | 5 | - Install WSL (see [microsoft documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10)) 6 | - Install X Server for Windows (I used [VcXsrv](https://sourceforge.net/projects/vcxsrv/)). 7 | - Install [Mesa](https://wiki.debian.org/Mesa) with `sudo apt install mesa-utils` (needed because there are missing libraries for the x11 display used by Pharo). 8 | > Note: The Mesa dependency may be overkill. On the [Pharo install page](https://pharo.org/web/gnu-linux-installation-64) there's mention of some things to do for Ubuntu 16. 9 | - Install Pharo: 10 | 11 | ```bash 12 | $ mkdir MyPharo 13 | $ cd MyPharo/ 14 | $ curl -L https://get.pharo.org/64/ | bash 15 | ``` 16 | 17 | The last step can also be the Pharo Launcher. 18 | 19 | > Note: Last time it has been tested, only Pharo of version >= 6 64bit could be run. 20 | > Pharo 32bits is not compatible because of a missing part of the kernel. 21 | 22 | For other Pharo/WSL issues, see [this blog](https://fuhrmanator.github.io/2019/02/27/Pharo-in-WSL.html). 23 | -------------------------------------------------------------------------------- /General/ImageFileFormat.md: -------------------------------------------------------------------------------- 1 | # Image file format 2 | Pharo image is a binary file containing a snapshot of the runtime. 3 | However, there is only a little documentation about its structure (how information is encoded as bytes). 4 | This page is an early work to document the binary format of Pharo images. 5 | 6 | - [Determinate the format of an image](#determinate-the-format-of-an-image) 7 | - [Image format accross Pharo versions](#image-format-accross-pharo-versions) 8 | 9 | ## Determinate the format of an image 10 | Each image has a format. The format can be retrieved by reading the 4 first bytes of an image file. 11 | These bytes encode an integer from least significant to most significant byte (little-endian). 12 | 13 | On MacOS, you can use `od` shell command to show these 4 bytes: 14 | 15 | ```bash 16 | od -t x1 -N 4 Pharo.image 17 | ``` 18 | 19 | You will get an output as follow: 20 | 21 | ``` 22 | 0000000 b5 09 01 00 23 | 0000004 24 | ``` 25 | 26 | Which correspond to `68021` in decimal. 27 | 28 | ## Image format accross Pharo versions 29 | 30 | | Pharo version | Image format code | Image first 4 bytes (hex) | 31 | |:-----------------------------|:------------------|:--------------------------| 32 | | version <= 1.3 | 6504 | 68 19 00 00 | 33 | | 1.3 < version <= 5.0-preSpur | 6505 | 69 19 00 00 | 34 | | version (32bits) >= 5.0 | 6521 | 79 19 00 00 | 35 | | version (64bits) >= 5.0 | 68021 | b5 09 01 00 | 36 | -------------------------------------------------------------------------------- /General/Travis.md: -------------------------------------------------------------------------------- 1 | # Setting up Travis Continuous Integration 2 | 3 | > IMPORTANT NOTE: Since Travis is becoming a pay to use service, it is possible that this documentation will not be updated anymore. 4 | > [A page on how to use Github Actions](GithubActions.md) in order to have a continuous integration is already available on this wiki. 5 | 6 | Your repository should have two extra hidden files: `.travis.yml` and `.smalltalk.ston`. 7 | In addition, you may want to have a `.coveralls` configuration to support automatic coverage computation. 8 | 9 | # `.travis.yml` 10 | Here is a basic `.travis.yml` that configure travis to create a matrix to run your projects tests on both linux and osx plateforms and for both Pharo 8.0 and Pharo 7.0 64 bits. 11 | 12 | ```yaml 13 | language: smalltalk 14 | sudo: false 15 | 16 | os: 17 | - linux 18 | - osx 19 | 20 | smalltalk: 21 | - Pharo64-8.0 22 | - Pharo64-7.0 23 | ``` 24 | 25 | # `.smalltalk.ston` 26 | `.smalltalk.ston` is the file where you specify the baseline to use for your project and the packages containing the tests (used to compute coverage). 27 | 28 | ``` 29 | SmalltalkCISpec { 30 | #loading : [ 31 | SCIMetacelloLoadSpec { 32 | #baseline : 'EnlumineurFormatter', 33 | #directory : 'src', 34 | #platforms : [ #pharo ] 35 | } 36 | ], 37 | #testing : { 38 | #coverage : { 39 | #packages : [ 'EnlumineurFormatter-Tests' ] 40 | } 41 | } 42 | } 43 | ``` 44 | 45 | # `.coveralls.yml` 46 | If one have a coveralls account, one can add a `.coveralls.yml` file with the coveralls token of their project. 47 | 48 | 49 | ```yaml 50 | service_name: travis-pro 51 | repo_token: twxvbgLWXzoj3syZg3eaYfBZxCKEbensg 52 | ``` 53 | -------------------------------------------------------------------------------- /General/CodingConventions.md: -------------------------------------------------------------------------------- 1 | # Coding conventions 2 | 3 | Pharo is full of implicit coding conventions. 4 | 5 | This page aims to document all those conventions to help newcomers write Pharo code as per the community's idioms. 6 | 7 | ## Tests conventions 8 | 9 | Pharo has some conventions when it comes to tests. This section covers those. 10 | 11 | **Package name** 12 | 13 | It is preferred to store tests in a separate package rather than in the package of the tested classes. 14 | The name of this package should be `NameOfOriginalPackage-Tests`. 15 | 16 | For example, if one wants to add tests to `Material-Design-Lite-Core`, the tests should be in a package called `Material-Design-Lite-Core-Tests`. 17 | 18 | **Class name** 19 | 20 | Tests classes (subclasses of `TestCase`) should end with the suffix `Test` (and not `Tests` because a test class is a test case). 21 | 22 | In the case of unit tests, the name of the class should be `MyClassTest`. For example, if one wants to add unit tests of `MDLButton`, the test class will be named `MDLButtonTest`. 23 | 24 | **Method name** 25 | 26 | Test method names in Pharo need to be prefixed with `test`. This is the way the test framework recognizes them as test methods. 27 | 28 | In case of a unit test on a method of the tested class, the name should be prefixed by `test` followed by the name of the method to test. 29 | 30 | For example: 31 | - The unit test for `#click` will be named `#testClick` 32 | - The unit test for `#clickElement:` will be named `#testClickElement` 33 | - The unit test for `#clickElement:withShiftPressed:` will be named `#testClickElementWithShiftPressed` 34 | 35 | By doing that, a new icon next to your actual method name will appear in the system browser. 36 | This icon allows one to launch the unit test of the method via a click. 37 | -------------------------------------------------------------------------------- /PharoProjects/OS.md: -------------------------------------------------------------------------------- 1 | # Basic interactions with the OS 2 | This page describes basic interactions with the OS. The code snippet below should be working on all OS and are built-in: you do not need to install an external project to use them. 3 | 4 | - [Execute shell command](#execute-shell-command) 5 | - [Write environment variable](#write-environment-variable) 6 | - [Read environment variable](#read-environment-variable) 7 | 8 | ## Execute shell command 9 | The following code execute a shell command and returns an integer which is the return code of the executed command. 10 | If the return code is `0`, the execution of the command is successful. Else, the integer returned is the error code generated by the shell command. 11 | 12 | ```Smalltalk 13 | LibC uniqueInstance 14 | system: 'echo "foo" >> /tmp/foo.txt' 15 | ``` 16 | 17 | To retrieve the output of a command directly in Pharo, use `#resultOfCommand:` 18 | 19 | ```Smalltalk 20 | LibC uniqueInstance 21 | resultOfCommand: 'echo "foo"'. "'foo 22 | '" 23 | ``` 24 | 25 | ## Write environment variable 26 | The environment behaves similarly to a dictionary when it comes to write a variable. 27 | 28 | ```Smalltalk 29 | Smalltalk os environment at: 'FOO' put: 'bar'. 30 | Smalltalk os environment at: 'FOO' ifAbsentPut: 'bar' 31 | ``` 32 | 33 | > Note: Before Pharo 7, `#setEnv:value:` message was used. This message is part of the low-level API and should not be used directly. 34 | 35 | ## Read environment variable 36 | As for writing a variable, environment provide an API similar to `Dictionary` to read a variable. 37 | 38 | ```Smalltalk 39 | Smalltalk os environment at: 'FOO'. 40 | Smalltalk os environment at: 'FOO' ifAbsent: [ 'Nope :-(' ]. 41 | Smalltalk os environment at: 'FOO' ifPresent: [ :value | "Do something interesting." ] 42 | ``` 43 | 44 | > Note: Before Pharo 7, #getEnv: message was used. This message is now deprecated and should not be used. 45 | -------------------------------------------------------------------------------- /ExternalResources/Community.md: -------------------------------------------------------------------------------- 1 | # Community 2 | This page lists links to external resources created by members of Pharo (and sometimes other smalltalks) community. 3 | Links are ranked in the lexicographic order which means that the position of a link in the list is not representative of the quality of the content. 4 | 5 | This page exists for the sake of discoverability of Pharo community. 6 | 7 | **We do not take any responsibility for content published in these external resources as we have no control on it.** 8 | 9 | - [https://astares.blogspot.com](https://astares.blogspot.com) - Blog related to Pharo in general. 10 | - [https://blog.sebastiansastre.co](https://blog.sebastiansastre.co) - Blog related to Pharo in general. 11 | - [https://clementbera.wordpress.com](https://clementbera.wordpress.com) - Blog related to the Pharo virtual machine and its development. 12 | - [https://endormitoire.wordpress.com/2016/10/03/freewill-in-progress-4/](https://endormitoire.wordpress.com/2016/10/03/freewill-in-progress-4/) - Blog related to Pharo in general. 13 | - [https://fuhrmanator.github.io](https://fuhrmanator.github.io) - Blog related to Moose and Pharo in general but not only. 14 | - [https://masteringobjects.wordpress.com](https://masteringobjects.wordpress.com) - Blog related to Pharo development. 15 | - [https://medium.com/@i.oleks](https://medium.com/@i.oleks) - Blog related to Pharo, AI and machine learning. 16 | - [https://medium.com/concerning-pharo](https://medium.com/concerning-pharo) - Blog related to Pharo in general, multiple authors involved. 17 | - [https://medium.com/@juliendelplanque](https://medium.com/@juliendelplanque) - Blog related to Pharo in general. 18 | - [http://www.mirandabanda.org/cogblog/](http://www.mirandabanda.org/cogblog/) - Blog for open-smalltalk-vm. 19 | - [https://thiscontext.com](https://thiscontext.com) - Blog related to caffeine, a smalltalk vm in Javascript and other smalltalk topics. 20 | - [https://80738163270632.blogspot.com/] - Blog related to Pharo in general. 21 | -------------------------------------------------------------------------------- /PharoProjects/Numbers.md: -------------------------------------------------------------------------------- 1 | # Numbers 2 | This page provides some hints for using Pharo's numbers. For more detailled information, check [Pharo by Example book](http://books.pharo.org/pharo-by-example). 3 | 4 | 5 | ## Numbers are not primitive 6 | As written in [Pharo by Example book](http://books.pharo.org/pharo-by-example), 7 | 8 | > Remarkably, numbers in Smalltalk are not primitive data values but true objects. Of course numbers are implemented efficiently in the virtual machine, but the Number hierarchy is as perfectly accessible and extensible as any other portion of the Smalltalk class hierarchy. - [Pharo by Example](http://books.pharo.org/pharo-by-example), Chapter 8 Section 2 9 | 10 | Which is an interesting feature because it means that extension methods can be added to create objects holding a quantity. This is what is done for `Duration`s: 11 | 12 | ```Smalltalk 13 | 5 seconds. "0:00:00:05" 14 | ``` 15 | 16 | `#seconds` method creates a new instance of `Duration` representing the number second required. 17 | 18 | ## Scaled decimals 19 | Scaled decimals allow one to model rationals. That is to say numbers with a fixed number of decimals. They are handy when dealing with money for example. It is possible to create a ScaledDecimal from its litteral form using the `s` notation: `1.45s2` which will store 1.45 with 2 digits precision in decimals. 20 | 21 | ## Special numbers 22 | - Infinity: `Float infinity` 23 | - Negative infinity: `Float negativeInfinity` 24 | - Not a number: `Float nan` 25 | - Pi, 2\*Pi, 3\*Pi: `Float pi. Float twoPi. Float threePi` 26 | - Euler's number: `Float e` 27 | 28 | ## Parse number 29 | The class-side methods `#readFrom:` and `#readFrom:base:` of `Number` class allow one to parse a number from a `String`. Here are some examples: 30 | 31 | ```Smalltalk 32 | Number readFrom: '10'. "10" 33 | Number readFrom: '10' base: 2. "2" 34 | Number readFrom: '1.0'. "1.0" 35 | ``` 36 | 37 | A specific subclass of `Number` can be used to ensure that the object created by the parser is of a specific kind: 38 | 39 | ```Smalltalk 40 | Integer readFrom: '10'. "10" 41 | Float readFrom: '1.0'. "1.0" 42 | ``` 43 | -------------------------------------------------------------------------------- /General/ProgressBar.md: -------------------------------------------------------------------------------- 1 | # Progress bar 2 | 3 | This document covers different ways to display a progress bar during code execution. 4 | 5 | ## Progress bar on iterators 6 | 7 | The easiest way to create a progress bar is to use the method `do:displayingProgress:`. This method is available on Collections and adds a progress bar automatically updated during iterations. 8 | 9 | ```Smalltalk 10 | (1 to: 100) do: [ :each | each logCr. 100 milliSecond wait. ] displayingProgress: [ :each | 'Iterating step ' , each asString ] 11 | ``` 12 | 13 | Refresh time can also be customized if better performances are needed. For example, the following code will update the progress bar every 2 seconds: 14 | 15 | ```Smalltalk 16 | (1 to: 100) do: [ :each | each logCr. 100 milliSecond wait. ] displayingProgress: [ :each | 'Iterating step ' , each asString ] every: 2000 17 | ``` 18 | 19 | ## Use Jobs 20 | 21 | An other way to display a progress bar is to use Jobs. 22 | 23 | ```Smalltalk 24 | [:job | job title: 'Let us get started'. 25 | 1 to: 10 do: [:each | 26 | job 27 | progress: (0.1 * each); 28 | title: 'Youpi ', each printString. 29 | (Delay forMilliseconds: 100) wait. 30 | ] ] asJob run 31 | ``` 32 | 33 | Or using UIManager: 34 | 35 | ```Smalltalk 36 | UIManager default 37 | displayProgress: 'Let us get started' 38 | from: 1 39 | to: 10 40 | during: [ :bar | 41 | 1 to: 10 do: [:each | 42 | bar 43 | value: each; 44 | title: 'Youpi ', each printString. 45 | (Delay forMilliseconds: 100) wait. 46 | ] ] 47 | ``` 48 | 49 | Be careful while using this method. It might cause performance issues when time between two steps is short. 50 | 51 | However, the following code shows a way to avoid these issues. 52 | 53 | ```Smalltalk 54 | UIManager default 55 | displayProgress: 'Let us get started' 56 | from: 1 57 | to: 40 58 | during: [ :bar | | lastUpdate | 59 | lastUpdate := 0. 60 | 1 to: 40 do: [:each | 61 | ((Time millisecondsSince: lastUpdate) >= 500) ifTrue: [ 62 | bar 63 | value: each; 64 | title: 'Youpi ', each printString. 65 | lastUpdate := Time millisecondClockValue 66 | ]. 67 | (Delay forMilliseconds: 100) wait. 68 | ] ] 69 | ``` 70 | 71 | The trick is to leave at least 500 milliseconds between two updates instead of updating the bar each time we call `value:` or `title:`. 72 | -------------------------------------------------------------------------------- /General/CJKCharacter.md: -------------------------------------------------------------------------------- 1 | # Using CJK (Chinese, Japanese, and Korean) characters 2 | 3 | Pharo's default font settings for code (Source Code Pro) and UI (Source Sans Pro) are unable to handle [CJK characters](https://en.wikipedia.org/wiki/CJK_characters), this page explains how to display them properly in Pharo. 4 | 5 | ![Preview string for chinese characters under Source Code Pro](CJKCharacter_Screenshot_1.png) 6 | 7 | Operating systems may come with fonts that support those characters but they are usually not monospaced which is not good for displaying code. If one need to display CJK characters in Pharo, it is recommended to install a monospace font which also covers CJK characters. Some of them are [`Noto Sans Mono CJK`](https://www.google.com/get/noto/) , `Microsoft YaHei Mono`, [`WenQuanYi Zen Hei Mono`](http://wenq.org). 8 | 9 | Note one must enable the option `Update fonts at startup` first and restart Pharo to make the font selection dialog below show all available fonts: 10 | 1. Select menu `Pharo` -> `Settings` to show the `Settings Browser`. 11 | 2. Enable `Appearance` -> `Use Free type...` -> `Update fonts at startup`, this can be disabled later after one changes the fonts. 12 | 13 | ![Preview string for chinese characters under Microsoft YaHei Mono](CJKCharacter_Screenshot_2.png) 14 | 15 | Note that on Windows 10, one may need to manually copy font files to `C:\Windows\Fonts\`. 16 | 17 | Here is a code sample: 18 | 19 | ```Smalltalk 20 | StandardFonts 21 | defaultFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9); 22 | codeFont: (LogicalFont familyName: 'Microsoft YaHei Mono' pointSize: 10); 23 | listFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9); 24 | menuFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9); 25 | buttonFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9); 26 | windowTitleFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 10); 27 | balloonFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 8); 28 | haloFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 8). 29 | ``` 30 | 31 | ## Related links: 32 | 33 | https://www.samadhiweb.com/blog/2019.02.22.windows.multilingual.html 34 | http://forum.world.st/Japanese-Fonts-td4928056.html 35 | http://forum.world.st/im-using-pharo-7-with-linux-env-but-cannot-input-korean-td5095342.html 36 | -------------------------------------------------------------------------------- /MANIFEST.md: -------------------------------------------------------------------------------- 1 | # Pharo wiki manifest 2 | 3 | This file will explain the goals of this project and define its boundaries. 4 | 5 | Pharo-wiki is a user maintained wiki on the programming language and development environment Pharo and its ecosystem. 6 | 7 | The goals of the project are to provide: 8 | - documentation on parts of Pharo that are not yet or poorly documented; 9 | - a centralized source of information on Pharo; 10 | - pointers to existing documentation; 11 | - tips on possible workflow on Pharo using all the strength of the environment; 12 | - references to external libraries; 13 | - migration guides between differents versions of Pharo. 14 | 15 | The project should be easy to contribute to (with a github account the user should just have to edit a file on the github interface to contribute) 16 | 17 | To be easy to contribute, this project is written in Markdown and hosted on github. Anyone with a github account can easily provide a Pull Request. (See [Contribution guide](CONTRIBUTION.md)) 18 | 19 | To achieve these goals, the project is divided into the following sections: 20 | 21 | * [Beginners](https://github.com/pharo-open-documentation/pharo-wiki#beginners) - guides for beginners who have just recently discovered Pharo. 22 | * [General](https://github.com/pharo-open-documentation/pharo-wiki#general) - pages describing some of Pharo mechanism and guides on possible workflows. 23 | * [Pharo projects](https://github.com/pharo-open-documentation/pharo-wiki#pharo-projects) - documentation about subprojects contained in the Pharo general distribution. 24 | * [External projects](https://github.com/pharo-open-documentation/pharo-wiki#external-projects) - information about external projects. Most of the pages give some examples to give an idea on how those project work and offer comparisons between multiple projects around the same theme. 25 | * [Migration guidelines](https://github.com/pharo-open-documentation/pharo-wiki#migration-guidelines) - migration guides between different versions of Pharo. 26 | * [External ressources](https://github.com/pharo-open-documentation/pharo-wiki#external-ressources) - links to ressources not maintained by the wiki community but interesting to check-out. 27 | 28 | As long as they fit the goals of the wiki, the entries of this project can be: 29 | - documentation 30 | - tutorials 31 | - guides 32 | - tips and tricks 33 | 34 | If you want to contribute but you are not sure your contribution fits the goals of the project, do not hesitate to open an issue to ask the maintainers for advice. 35 | 36 | If you wish to contribute, you should read the [contribution guide](CONTRIBUTION.md). 37 | -------------------------------------------------------------------------------- /PharoProjects/DynamicVariables.md: -------------------------------------------------------------------------------- 1 | # Dynamic variables 2 | 3 | Pharo contains a system of dynamic variables which are global variables whose value can be changed during the execution of a process. 4 | 5 | > Be careful when you use these variables. They should not be used just as a global variable to make access to it easier in the code. 6 | 7 | A logger system is good example of the usefulness of dynamic variables. In such a system, we can imagine that we have a default logger that will be used to record logs. However, in some specific cases we want to use a custom logger. In that case a dynamic variable can do the work. If you wish to see it at work you can check this [logger project using it](https://github.com/jecisc/TinyLogger). 8 | 9 | ## Create a new dynamic variable 10 | 11 | To create a new dynamic variable you just need to create a new subclass of `DynamicVariable`: 12 | 13 | ```Smalltalk 14 | DynamicVariable subclass: #MyVariable 15 | slots: { } 16 | classVariables: { } 17 | package: 'MyProject' 18 | ``` 19 | 20 | ## Add a default value 21 | 22 | It is possible to assign a default value to your dynamic variable. To do so, you need to add a `default` method. 23 | 24 | ```Smalltalk 25 | MyVariable>>default 26 | ^ MyDefaultObject 27 | ``` 28 | 29 | ## Use your dynamic variable 30 | 31 | To use your variable, just send the `value` message to it. If you have no default value, do not forget to manage the case where it can be nil if it can happen. 32 | 33 | ```Smalltalk 34 | MyVariable value doSomething 35 | ``` 36 | 37 | ## Change the value of the variable in a process 38 | 39 | If you need to change the value of the variable for the execution of a specific process, just use the `value:during:` message. 40 | 41 | ```Smalltalk 42 | MyVariable value: MyNewObject during: [ 43 | self doAnActionUsingTheVariable. 44 | ] 45 | ``` 46 | 47 | ## Example 48 | 49 | Here is the way dynamic variables are used in the `TinyLogger` project cited above. 50 | 51 | ```Smalltalk 52 | DynamicVariable subclass: #TinyCurrentLogger 53 | slots: { } 54 | classVariables: { } 55 | package: 'TinyLogger-Core' 56 | ``` 57 | 58 | ```Smalltalk 59 | TinyCurrentLogger>>default 60 | ^ TinyLogger default 61 | ``` 62 | 63 | ```Smalltalk 64 | Object>>record: aString 65 | TinyCurrentLogger value record: aString 66 | ``` 67 | 68 | ```Smalltalk 69 | Object>>execute: aBlock recordedAs: aString 70 | TinyCurrentLogger value execute: aBlock recordedAs: aString 71 | ``` 72 | 73 | ```Smalltalk 74 | TinyCurrentLogger value: (TinyLogger new addTranscriptLogger; yourself) during: [ 75 | 'test' record. 76 | TinyCurrentLogger value record: 'Test2' 77 | ] 78 | ``` 79 | 80 | 81 | -------------------------------------------------------------------------------- /ExternalProjects/Export/CSV.md: -------------------------------------------------------------------------------- 1 | # CSV support in Pharo 2 | Currently, Pharo provides one main framework to handle the [CSV format](https://fr.wikipedia.org/wiki/Comma-separated_values): NeoCSV. 3 | 4 | ## NeoCSV 5 | NeoJSON is actually maintained by Sven Van Caekenberghe on [github](https://github.com/svenvc/NeoCSV). 6 | This section shows some quick examples but there is a great [documentation made by Sven](https://github.com/svenvc/docs/blob/master/neo/neo-csv-paper.md) and a chapter in [Enterprise Pharo (chapter 7)](http://books.pharo.org/enterprise-pharo/). 7 | 8 | > NeoCSV provides utilities to map Smalltalk objects to CSV lines, this page does not cover this topic to avoid duplication with the great documentation available in [Sven's documentation](https://github.com/svenvc/docs/blob/master/neo/neo-csv-paper.md) and [Enterprise Pharo (chapter 7)](http://books.pharo.org/enterprise-pharo/). Check it out if you need to use such feature! 9 | 10 | ### Install 11 | To install NeoCSV, simply execute the following code snippet in a playground: 12 | ```Smalltalk 13 | Metacello new 14 | repository: 'github://svenvc/NeoCSV/repository'; 15 | baseline: 'NeoCSV'; 16 | load 17 | ``` 18 | 19 | ### Parse CSV 20 | - From `String`: 21 | ```Smalltalk 22 | str := 'id, name 23 | 0, Julien 24 | 1, Cyril 25 | 2, Guillaume 26 | '. 27 | str readStreamDo: [ :s | 28 | (NeoCSVReader on: s) 29 | skipHeader; 30 | addIntegerField; 31 | addField; 32 | upToEnd ] 33 | ``` 34 | 35 | - From `Stream`: 36 | ```Smalltalk 37 | stream := 'id, name 38 | 0, Julien 39 | 1, Cyril 40 | 2, Guillaume 41 | ' readStream. 42 | 43 | (NeoCSVReader on: stream) 44 | skipHeader; 45 | addIntegerField; 46 | addField; 47 | upToEnd 48 | ``` 49 | 50 | - Read from CSV file: 51 | ```Smalltalk 52 | '/path/to/file.csv' asFileReference 53 | readStreamDo: [ :readStream | 54 | (NeoCSVReader on: readStream) 55 | skipHeader; 56 | addIntegerField; 57 | addField; 58 | upToEnd ] 59 | ``` 60 | 61 | ### Generate CSV 62 | Let `data` be defined as: 63 | ```Smalltalk 64 | data := #( 65 | (0 'Julien') 66 | (1 'Cyril') 67 | (2 'Guillaume')). 68 | ``` 69 | 70 | - To generate a CSV `String`: 71 | ```Smalltalk 72 | String streamContents: [ :writeStream | 73 | (NeoCSVWriter on: writeStream) 74 | writeHeader: #(id name); 75 | nextPutAll: data ] 76 | ``` 77 | 78 | - To generate CSV on a `Stream`: 79 | ```Smalltalk 80 | (NeoCSVWriter on: writeStream) 81 | writeHeader: #(id name); 82 | nextPutAll: data 83 | ``` 84 | 85 | - To write a CSV file: 86 | ```Smalltalk 87 | '/path/to/file.csv' asFileReference 88 | writeStreamDo: [ :writeStream | 89 | (NeoCSVWriter on: writeStream) 90 | writeHeader: #(id name); 91 | nextPutAll: data ] 92 | ``` 93 | -------------------------------------------------------------------------------- /General/Profiling.md: -------------------------------------------------------------------------------- 1 | # Profiling 2 | Profiling a program is the act of measuring, for example, the time or space it takes to execute. 3 | 4 | - [Time Profiling](#time-profiling) 5 | * [Programmatically open a Time Profiler](#programmatically-open-a-time-profiler) 6 | * [Utility methods on blocks to profile](#utility-methods-on-blocks-to-profile) 7 | * [Interactively open a Time Profiler](#interactively-open-a-time-profiler) 8 | - [Space Profiling](#space-profiling) 9 | 10 | ## Time Profiling 11 | ### Programmatically open a Time Profiler 12 | If `SimpleGridExample new open` is the program you want to profile, run: 13 | ```Smalltalk 14 | TimeProfiler spyOn: [ SimpleGridExample new open ] 15 | ``` 16 | Result: a breakdown of the methods in which the program spent time. 17 | 18 | ![image](Profiling_Image_TimeProfilerFromCommandLine.png) 19 | 20 | > If your block execution time is too fast (~ < 3ms), the time profiler will not display any result. 21 | 22 | The time profiler UI is composed of multiple parts: 23 | - *Tallies tree* displays a tree of all the nested method calls of the execution with the percentage of time spent in each call. The tree stops at primitive calls or calls that are too fast to be benchmarked (~ < 3ms) 24 | - *Code* displays the code of the selected method in the `tallies tree` 25 | - *Statistics* displays memory and garbage collection statistics. Those informations may be useful if too much execution time is spent in the full or incremental garbage collection. This may signal that the code executed create too many temporary objects. The code can then be reviewed to create less copies or temporary objects. If it is not possible, consider changing the parameter of the VM to do less garbage collection during the execution of some algorithms. 26 | - *Full report* displays textual informations such as the tallies tree and statistics, but also informations on leaf methods where most of the time is spent. (Section `**Leaves**`) This can be a good source of information to find bottlenecks where the time is spent. 27 | 28 | ### Utility methods on blocks to profile 29 | If `SimpleGridExample new open` is the program you want to profile, **inspect** or **print**: 30 | 31 | ```Smalltalk 32 | [ SimpleGridExample new open ] bench. 33 | ``` 34 | 35 | Result: the number of times the profiler was able to run the program per second. 36 | 37 | ![image](Profiling_Image_Bench.png) 38 | 39 | You can also check the execution time of a set of instructions by inspecting or printing the result of the `timeToRun` method on blocks like this: 40 | 41 | ```Smalltalk 42 | [ SimpleGridExample new open ] timeToRun 43 | ``` 44 | 45 | ### Interactively open a Time Profiler 46 | You can access a UI for the time profiler tool via the menu bar. 47 | 48 | ![image](Profiling_Image_TimeProfilerMenuItem.png) 49 | 50 | Result: type your code in the top box and click "Profile it". 51 | 52 | ![image](Profiling_Image_TimeProfilerToolUI.png) 53 | 54 | ## Space Profiling 55 | Imagine you want to know how much instances of the classes Point and TextMorph there are in the system, and how much space they occupy. **Inspect**: 56 | ```Smalltalk 57 | ((SpaceTally new spaceTally: (Array with: TextMorph with: Point)) 58 | asSortedCollection: [:a :b | a spaceForInstances > b spaceForInstances]) 59 | ``` 60 | Result: 61 | 62 | ![image](Profiling_Image_SpaceTally.png) 63 | -------------------------------------------------------------------------------- /PharoProjects/RichText.md: -------------------------------------------------------------------------------- 1 | # Rich text in Pharo 2 | 3 | `Text` object models rich text. That is to say text that can be stylised with **bold**, *italics*, colors, different fonts and a few other things. The class `Text` is one of the really ancient classes in smalltalk. 4 | 5 | - [Quickstart](#quickstart) 6 | - [TextEmphasis](#textemphasis) 7 | - [Colors](#colors) 8 | - [Different fonts](#different-fonts) 9 | - [Clickable text](#clickable-text) 10 | - [Inline images](#inline-images) 11 | 12 | ## Quickstart 13 | Here is a quick example illustrating how attributes can be added to `Text` object to create rich text in Pharo: 14 | 15 | ```Smalltalk 16 | text := 'Hello World!' asText. 17 | text 18 | addAttribute: TextEmphasis italic from: 7 to: 11; 19 | addAttribute: TextEmphasis struckOut from: 7 to: 11; 20 | addAttribute: (TextColor color: Color red) from: 7 to: 11; 21 | addAttribute: (TextColor color: Color green) from: 12 to: 12. 22 | ``` 23 | 24 | ## TextEmphasis 25 | The class `TextEmphasis` defines a set of simple (no font change) changes you can do. See the class side of `TextEmphasis` for the supported styles of emphasis. 26 | 27 | It is possible to overlap the different emphasis styles: 28 | 29 | ```Smalltalk 30 | text := 'Hello World!' asText. 31 | text 32 | addAttribute: TextEmphasis italic from: 7 to: 11; 33 | addAttribute: TextEmphasis struckOut from: 7 to: 11. 34 | ``` 35 | 36 | ## Colors 37 | Colored text is done as shown below. Examine the class `Color` for other colors. 38 | 39 | ```Smalltalk 40 | text := 'Hello World!' asText. 41 | text 42 | addAttribute: (TextColor color: Color red) from: 7 to: 11; 43 | addAttribute: (TextColor color: Color green) from: 12 to: 12. 44 | ``` 45 | 46 | ## Different fonts 47 | Loading and managing fonts is an issue in itself. 48 | 49 | You can see which fonts you have available in your image using `StrikeFont actualFamilyNames`. 50 | 51 | Assume you have a font named: `Bitmap Source Sans Pro` (was the case on Macbook Pro, Pharo 8, fall 2019). 52 | 53 | You need to turn the font into a text attribute: 54 | 55 | ```Smalltalk 56 | largeAttribute := TextFontReference 57 | toFont: 58 | (StrikeFont 59 | familyName: 'Bitmap Source Sans Pro' 60 | pointSize: 20). 61 | 'My larger text' asText addAttribute: largeAttribute from: 4 to: 10. 62 | ``` 63 | 64 | This should give you 'My larger text' with 'larger' being in font size 20 and in the 'Bitmap Source Sans Pro' font. 65 | 66 | ## Clickable text 67 | It is possible to make text do stuff when clicked. This is obviously a huge area. One simple example is: 68 | 69 | ```Smalltalk 70 | textAction := TextAction new 71 | actOnClickBlock: [ 72 | Transcript nextPutAll: 'action clicked';cr;endEntry 73 | ]. 74 | 'My action text' asText addAttribute: textAction from: 4 to: 10. 75 | ``` 76 | 77 | ## Inline images 78 | It is possible to insert images into text. It is done using a `TextAnchor` attribute which can only be put on the text obtained using the expression `(String value: 1) asText`. The following example illustrates this: 79 | 80 | ```Smalltalk 81 | anchoredImage := 82 | (String value: 1) asText addAttribute: 83 | (TextAnchor new anchoredMorph: PolymorphSystemSettings pharoLogoForm ). 84 | 85 | ('Line before image\' withCRs asText), 86 | anchoredImage, 87 | ('\Line afterimage' withCRs asText). 88 | ``` 89 | 90 | There are further examples in the class comment of `TextAnchor`. 91 | 92 | > Note: 93 | > The inline images relies on the morphic system. Not all morphs seem to be able to be inlined in text in Pharo. 94 | > 95 | > In addition, you will most likely get the best results if you put images larger than the font size on a line by themself. The class comment of `TextAnchor` has an example of inlining a small icon. 96 | -------------------------------------------------------------------------------- /General/IcebergOnWindows.md: -------------------------------------------------------------------------------- 1 | # Iceberg on Windows Workaround 2 | 3 | - [Make path to the Pharo Image shorter](#make-path-to-the-pharo-image-shorter) 4 | - [Convert the repository to the Tonel format](#convert-the-repository-to-the-tonel-format) 5 | 6 | Long file names in Windows raise the error message “Failed to stat file ‘filename’: The filename or extension is too long”. 7 | 8 | The Windows problem with long filenames is a constraint of [libgit](https://libgit2.org/libgit2/#HEAD) library that is used in Pharo (Iceberg accesses git through this exact library). It occurs because FileTree format tends to have long paths and was one of the main drivers in creating the Tonel format. This error can occur, for example, when you are trying to clone your Pharo fork on Github into Pharo local. There are two possible ways to fix it: 9 | 10 | 1. Make path to Pharo Image short. 11 | 2. Convert repo to Tonel format — in Iceberg there is a menu item under one of the Extras menus. 12 | 13 | Here’s more about them: 14 | 15 | ## Make path to the Pharo Image shorter 16 | 17 | If you are simply using a standalone Pharo [download](http://pharo.org/download/#standalone), you can just move your image and VM a few folders up. However, if you are using [Pharo Launcher](http://pharo.org/download/), you have to access the settings, to change where it stores images it will create in the future, as well as move all the existing images and VMs up. Here’s how to do it. 18 | 19 | In Pharo Launcher, in the bottom right corner you can see a button ‘open settings’ — click on it. 20 | 21 | ![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_2.png) 22 | 23 | In the settings, if you expand the ‘Pharo Launcher’ tab you can see the following options: 24 | 25 | ![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_3.png) 26 | 27 | In the first, third and fourth options, change directories without disrupting the dependencies (images in ‘images’, template sources one folder up, etc). When you change the paths, the upper right corner of each of the text boxes will be yellow, which means unsaved changes (that is also the logic inside Pharo). You have to position your cursor in each of the text boxes and press (ctrl+s) to save the changes. 28 | 29 | Don’t forget that this section only means images and VMs it will create in the future, so you should also manually move your already existing images and VMs to the same folder you listed. 30 | 31 | Now, everything should work! 32 | 33 | ## Convert the repository to the Tonel format 34 | 35 | Note re FileTree/Tonel: A FileTree represents a hierarchy of files. [Tonel](https://github.com/pharo-vcs/tonel) is a file-per-class format — class and all methods are stored in a single file, which is better than having a file for each method because the code is easier to read outside of Pharo and it creates less files on the hard drive. Tonel also prevents some trouble with git on Windows due to number of files and subdirectory depth that create path exceeding windows limit. 36 | 37 | If you are using an older version of Pharo, you need to download Tonel by running the code below in a playground (in Pharo 7 and 8 it comes by default): 38 | 39 | ```Smalltalk 40 | Metacello new 41 | baseline: 'Tonel'; 42 | repository: 'github://pharo-vcs/tonel:v1.0.12'; 43 | load. 44 | ``` 45 | 46 | > Note: In Pharo 7 and 8 you don’t need any kind of script to convert to Tonel — there’s a UI option available. But in Pharo 6.1 you need to upgrade Iceberg first, and Tonel will come with it. Link with the script [here](https://github.com/pharo-vcs/iceberg/#for-pharo-61). 47 | 48 | With Tonel loaded, if you go to Iceberg repositories and right-click on the specific repository, you can go to ‘extra’ category and click on ‘convert repository sources to tonel’ button. It will migrate the code for you. 49 | 50 | ![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_4.png) 51 | 52 | > Note: this option is only possible if the repository isn’t already in the Tonel format. So if your problem is cloning the Pharo fork (Pharo repo is partially Tonel, partially Filetree), then the only option that will actually solve it, is  shortening the path. 53 | 54 | 55 | -------------------------------------------------------------------------------- /PharoProjects/Announcer.md: -------------------------------------------------------------------------------- 1 | # Announcer 2 | `Announcer` and `Announcement` classes provide an implementation of the [observer design pattern](https://en.wikipedia.org/wiki/Observer_pattern) in Pharo. 3 | As written on the wikipedia page, it aims to address the following problems: 4 | 5 | - A one-to-many dependency between objects should be defined without making the objects tightly coupled. 6 | - It should be ensured that, when one object changes state, an open-ended number of dependent objects are updated automatically. 7 | - It should be possible that one object can notify an open-ended number of other objects. 8 | 9 | This page provide a quick tutorial to get started with them. 10 | 11 | - [Getting started](#getting-started) 12 | - [Defining new kind of Announcement](#defining-new-kind-of-announcement) 13 | - [Using announcer for your subject object](#using-announcer-for-your-subject-object) 14 | 15 | ## Getting started 16 | The `Announcer` class implements a mechanism to: 17 | 1. Allow objects (the observers) to subscribe to announcements 18 | 2. Manage objects subscriptions 19 | 3. Allow the object holding the announcer (the subject) to announce events 20 | 21 | For example, there is an announcer available to let objects listen to announcements (events) concerning the system: `SystemAnnouncer uniqueInstance`. 22 | Such announcements include: 23 | - `ClassAdded` 24 | - `ClassRemoved` 25 | - `MethodModified` 26 | - etc. 27 | 28 | If one wants to be notified when a class is removed, it is possible to subscribe an object to this specific announcement as follow. 29 | 30 | First, let's create the method `#whenClassAdded:` for the object that will listen to `ClassAdded` announcement. 31 | This method will be the hook called when such announcement has been announced. 32 | It takes the announcement sent by the subject as parameter. 33 | 34 | ```Smalltalk 35 | MyObjectListeningToClassAdded>>#whenClassAdded: aClassAdded 36 | Transcript 37 | show: aClassAdded classAffected name; 38 | show: ' has been added.'; 39 | cr 40 | ``` 41 | 42 | Then, we subscribe an instance of our object to the announcer. 43 | When doing that, it is needed to specify 44 | 1. Which kind of announcements (its class) our object listen to. 45 | 2. Which object listen to this kind of announcements. 46 | 3. Which method to call when the annoncement is sent. 47 | 48 | The previous step can be achieved as follow: 49 | 50 | ```Smalltalk 51 | SystemAnnouncer uniqueInstance 52 | when: ClassAdded send: #whenClassAdded: to: instanceOfMyObjectListeningToClassAdded 53 | ``` 54 | 55 | > Note: the SystemAnnouncer is a bit special because it is a subclass of `Announcer`. 56 | > Usually, when creating you own announcer, you do not subclass `Announcer` but rather use it directly by storing an instance in a dedicated instance variable (see Section "[Using announcer for your subject object](#using-announcer-for-your-subject-object)"). 57 | 58 | Once the code above has been executed, a message is printed in the Transcript each time a class has been added. 59 | To unsubscribe an object from an announcer, simply call `#unsubscribe:` method on the announcer. 60 | 61 | ```Smalltalk 62 | SystemAnnouncer uniqueInstance 63 | unsubscribe: instanceOfMyObjectListeningToClassAdded 64 | ``` 65 | 66 | ## Defining new kind of Announcement 67 | Creating a new kind of announcement to fit your needs is easy, just subclass `Announcement` class. 68 | For example, let's say you have an object that has a color. You want to allow observers to listen to color changes of the object. 69 | To do that, let's create a `ColorChangeAnnouncement` class: 70 | 71 | ```Smalltalk 72 | Announcement subclass: #ColorChangeAnnouncement 73 | slots: { #newColor } 74 | classVariables: { } 75 | package: 'MyPackage' 76 | ``` 77 | 78 | Your new kind of announcement aims to hold all the information you need. 79 | In our example, `ColorChangeAnnouncement` hold the new color in `#newColor` instance variable. 80 | 81 | ## Using announcer for your subject object 82 | The common pattern to use an `Announcer` in your subject object is to: 83 | 1. Create an `#announcer` instance variable which will contain the instance of `Announcer`. 84 | 2. Create an accessor method for `#announcer` instance variable that use lazy-initialization (so no announcer is created if no announcement is sent and no one wants to subscribe to events of the subject). 85 | 3. The subject object send announcements through its announcer. 86 | 87 | As an example, let's implement the object changing its color discussed in previous section" 88 | 89 | ```Smalltalk 90 | Object subclass: #MyObjectChangeColor 91 | slots: { #announcer. #color } 92 | classVariables: { } 93 | package: 'MyPackage' 94 | ``` 95 | 96 | Then we create the accessor for `#announcer` with lazy-initialisation. 97 | 98 | ```Smalltalk 99 | MyObjectChangeColor>>#announcer 100 | ^ announcer ifNil: [ announcer := Announcer new ] 101 | ``` 102 | 103 | And when the color of the object is updated, we announce it: 104 | 105 | ```Smalltalk 106 | MyObjectChangeColor>>#color: aColor 107 | color := aColor. 108 | self announcer 109 | announce: (ColorChangeAnnouncement new 110 | newColor: aColor; 111 | yourself) 112 | ``` 113 | -------------------------------------------------------------------------------- /General/Extensions.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | - [Extensions](#extensions) 4 | - [Use of Extension methods](#use-of-extension-methods) 5 | - [Add a new extension method](#add-a-new-extension-method) 6 | - [Define an extension method in versions prior to Pharo 7](#define-an-extension-method-in-versions-prior-to-pharo-7) 7 | - [Define an extension method since Pharo 7](#define-an-extension-method-since-pharo-7) 8 | - [Define an extension method programmatically](#define-an-extension-method-programmatically) 9 | - [Find methods currently extending a class](#find-methods-currently-extending-a-class) 10 | - [In versions prior to Pharo 7](#in-versions-prior-to-pharo-7) 11 | - [Since Pharo 7](#since-pharo-7) 12 | - [Find extensions programmatically](#find-extensions-programmatically) 13 | - [Package loading order is important](#package-loading-order-is-important) 14 | 15 | Pharo includes a system of extension methods. This feature allows the developer to add behavior (but not state) to existing objects in Pharo. 16 | 17 | > Note that it is only possible to add methods (behavior) as extension and not variables (state) 18 | 19 | There is no syntactic difference between calling an extension method and calling a method declared in the class. The main difference between methods and extension methods is that extension methods are stored in a different package than the class they are implemented on. 20 | 21 | ## Use of Extension methods 22 | 23 | Extension methods are useful when we want to use some behavior on an object, but it does not make sense to package it directly with the object. For example we might want to ask to a model object for information related to its display in a GUI, but to keep layers as cohesive as possible, we do not want display information stored in the code package of our application. In this case, we can add those methods to the model object but package those methods in a GUI package. 24 | 25 | Another case might be when you want to enhance the behavior of a package that is simply not your own. You could add the methods to the class in the different package, but committing those changes to source control is not practical (i.e., you don't want to make a branch of the package, and doing a pull request would take a long time, etc.). With extension methods, the changes you make to the foreign package are stored in your own package, so they belong to you. 26 | 27 | ## Add a new extension method 28 | 29 | Internally, an extension method is a method whose protocol has a pattern `*MyPackageExtendingMyClass`. 30 | 31 | Here is more detailed information about adding an extension method via Pharo's tooling. 32 | 33 | ### Define an extension method in versions prior to Pharo 7 34 | 35 | In the Pharo versions based on Nautilus system browser, extension methods are created when we categorize methods on a protocol beginning by a `*`. 36 | 37 | ![Add an extension method via Nautilus 1](Extensions_Image_NautilusAddExtension1.png?raw=true "Add an extension method via Nautilus 1") 38 | 39 | ![Add an extension method via Nautilus 2](Extensions_Image_NautilusAddExtension2.png?raw=true "Add an extension method via Nautilus 2") 40 | 41 | ### Define an extension method since Pharo 7 42 | 43 | Since Pharo 7 the default system browser is Calypso. To add an extension method in Calypso you need to use the "Move to package" menu entry. 44 | 45 | ![Add an extension method via Calypso](Extensions_Image_CalypsoAddExtension.png?raw=true "Add an extension method via Calypso") 46 | 47 | If you already have extensions in this package, you can also select the package in the list of extending packages in the protocol pane before adding a method. 48 | 49 | ### Define an extension method programmatically 50 | 51 | ```Smalltalk 52 | ExistingClass compile: 'myMethod 53 | ^ true' classified: '*MyPackage' 54 | ``` 55 | 56 | ## Find methods currently extending a class 57 | 58 | There are two ways to find which methods are extensions where they are located: 59 | 60 | - Browse a class and check the protocols pane. (See examples below) 61 | 62 | - Look at a package and check the bottom of the class pane. The last classes will appear in grey and will be the classes extended in that package. 63 | 64 | ### In versions prior to Pharo 7 65 | 66 | ![See an extension method via Nautilus](Extensions_Image_NautilusSeeExtensions.png?raw=true "See an extension method via Nautilus") 67 | 68 | ### Since Pharo 7 69 | 70 | ![See an extension method via Calypso](Extensions_Image_CalypsoSeeExtensions.png?raw=true "See an extension method via Calypso") 71 | 72 | ### Find extensions programmatically 73 | 74 | To find extension methods programmatically you can do something like: 75 | 76 | ```Smalltalk 77 | (Number methods select: #isExtension) groupedBy: #package 78 | ``` 79 | 80 | > **TODO: Add example of refactoring to an extension?** 81 | 82 | 83 | ## Package loading order is important 84 | 85 | One thing developers should take into account when using extensions is to have clean dependencies between its packages. A package extending classes from another package should be loaded *after* this package. 86 | 87 | For example, if my package `MyProject-GUI` extends `MyProject-Model`, `MyProject-Model` should always be loaded *before* `MyProject-GUI` is. For more details, see the dependencies sections in the [baseline guide](Baselines.md). 88 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # Contribution guidlines 2 | 3 | * [Suggest new pages](#suggest-new-pages) 4 | * [Entries structure](#entries-structure) 5 | * [Edit a page](#edit-a-page) 6 | * [Add a new page](#add-a-new-page) 7 | * [Deleting, Moving or Renaming a page](#deleting-moving-or-renaming-a-page) 8 | + [If the content is obsolete](#if-the-content-is-obsolete) 9 | + [If we want to move a page](#if-we-want-to-move-a-page) 10 | + [If we want to split a page](#if-we-want-to-split-a-page) 11 | + [If we want to rename a page](#if-we-want-to-rename-a-page) 12 | * [Review content](#review-content) 13 | 14 | ## Suggest new pages 15 | 16 | To suggest pages that could fit the wiki, the recommended way is to open an issue containing a summary of the page, the section in which it should be (General, Internal projects of Pharo or External projects of Pharo) and optionaly links to already existing documentation on the projects. 17 | 18 | On the language and environment part of the wiki we accept to document a part of the system that is already documented outside the wiki at the condition that we reference in a *See also* section those documentation. The goal is to have a centralized information and to provide alternative ways of explaining. 19 | 20 | If you wish to add the new entry yourself, see section [Add a new page](#add-a-new-page). 21 | 22 | ## Entries structure 23 | 24 | The entries structure is free but we still have some conventions. 25 | 26 | * Documentation on external projects should mostly contains small example, comparaisons between multiple projects, links to official documentations and repositories. We can accept documentation on the external projects in case there is none by the official maintainer. 27 | * Long entries should begin with a table of content. We recommand [https://ecotrust-canada.github.io/markdown-toc/](https://ecotrust-canada.github.io/markdown-toc/). 28 | * References to external/decentralized documentation should be in a *See also* section at the end of the entry. 29 | * Smalltalk code snippets should use *tabulation* for source code indentation. 30 | * Smalltalk code snippets should be highlighted using this format: 31 | 32 | 33 |
```Smalltalk
34 |  Code
35 | ```
36 | 37 | ## Edit a page 38 | 39 | If you see some typo, wrong informations or missing informations you can report it in the issues or you can also edit the document yourself and create a pull request. 40 | 41 | Creating a PR is as easy as clicking on the Edit (pen) button, updating the document and propose the changes. 42 | 43 | ![Gif showing how to edit a page](Resources/EditPage.gif) 44 | 45 | ## Add a new page 46 | 47 | In order to add a page you can just go into the folder of the section where the page should be and use the "Create new file button". 48 | 49 | ![Gif showing how to add a new page](Resources/CreatePage.gif) 50 | 51 | If you need to integrate images in your entry, add them next to the Markdown file with an name following this pattern: `_Image_.extension`. For example for an image illustrating `Iceberg` in a page called `VCS.md`, the image should be named `VCS_Image_IcebergIllustration.png`. 52 | 53 | Once the page is created you need to add it to the [README.md](README.md) in the right section. 54 | 55 | > Note: If you have contents to start a page but don't have the time or the knowledge to finish it, it is advised to propose a pull request with the content you have already. Then, one can open issues with the missing sections pointing to the concerned page. 56 | 57 | An entry in the README can also have a one short sentense explaining the purpose of the page. 58 | 59 | The pages focus mainly on the latest stable Pharo version. This does not mean we refuse contribution on older or development version of Pharo, but those should be complement of the current stable version. 60 | 61 | ## Deleting, Moving or Renaming a page 62 | 63 | **/!\\ We never delete a page. /!\\** 64 | 65 | This is a rule in this wiki. What is more annoying than a 404 when we look for documentation? 66 | 67 | Instead we have different strategies depending on why we want to delete a page. 68 | 69 | ### If the content is obsolete 70 | 71 | If the content is obsolete, we do not delete the page but we add a note (using `> OBSOLETE : bla`) at the beginning explaining why the guide is obsolete. The guide can be removed from the README. 72 | 73 | ### If we want to move a page 74 | 75 | If we want to move a page, we can copy it to the new location and let the old page at the original location with an explanation and a link to the new page. 76 | 77 | ### If we want to split a page 78 | 79 | Sometimes a page is too big and would win to be splited. In that case the content can be extracted in multiple pages but the original page should stay and contains an index of the new pages. 80 | 81 | ### If we want to rename a page 82 | 83 | If we want to rename a page, we can copy it with the new name and let the old page at the original location with an explanation and a link to the new page. 84 | 85 | ## Review content 86 | 87 | It is really helpful to get reviews of the wiki's content. This can be achieved in multiple ways: 88 | - Review a Pull Request. Comments, approvals and changes request on pull request will help the intergation of new contents. 89 | - Open issues on existing entries. 90 | - Create a Pull Request to propose enhancements to an existing entry. 91 | -------------------------------------------------------------------------------- /General/MustKnowForBeginners.md: -------------------------------------------------------------------------------- 1 | # Must know for beginners 2 | 3 | This page includes knowledge about thing the Pharo community think important to know as a Pharo beginner. 4 | 5 | 6 | - [Navigate into the code](#navigate-into-the-code) 7 | * [Browse, Senders and Implementors](#browse-senders-and-implementors) 8 | * [Method source with it](#method-source-with-it) 9 | - [Interrupt the Pharo process](#interrupt-the-pharo-process) 10 | - [Debugging facilities](#debugging-facilities) 11 | 12 | ## Navigate into the code 13 | 14 | Pharo offers a lot of ways to navigate into the code, and most of those are used daily by Pharo developers. This section will highlight the most important ones. 15 | 16 | ### Browse, Senders and Implementors 17 | 18 | When reading code we often need to open an entity or to check who is using an entity. To do that, Pharo has different commands: 19 | * **Browse** (`CMD/CTRL + b`): This command will open a new system browser on the class you are currently focusing on 20 | * **Senders/References** (`CMD/CTRL + n`): This command will open a message browser with all the methods calling the method/symbol you are currently focusing on, or, in the case where you are focusing on a class, the references to this class. 21 | * **Implementors** (`CMD/CTRL + m`): This command will open a message browser with all the methods whose name is the name of the method/symbol you are currently focusing on, or, in the case where you are focusing on a class, the references to this class like `browse`. 22 | 23 | Alternatively, it is possible to navigate the code using the mouse and the keyboard. In most text editors of Pharo you can use the shortcut `CMD + (Shift +) click` on OSX or `Alt + (Shift +) right click` on Windows/Linux to browse senders, implementors, classes and references. 24 | 25 | Using `CMD + click` on OSX or `Alt + right click` on Windows/Linux allows one to: 26 | - Browse the implementors when you click on a method. 27 | - Browse the class when you click on a class. 28 | - Browse the class or implementors of a method represented by a symbol when you click on a symbol. 29 | 30 | Using `CMD + (Shift +) click` on OSX or `Alt + (Shift +) right click` on Windows/Linux allows one to: 31 | - Browse the senders when you click on a method. 32 | - Browse the references to a class when you click on a class. 33 | - Browse the references to a class or senders of a method represented by a symbol when you click on a symbol. 34 | 35 | > Warning: The click shortcuts on symbols are only working starting from Pharo 9. In the previous version, it will browse the ByteSymbol class. 36 | 37 | ### Method source with it 38 | 39 | It often happens that we want to see how a feature is done, or we want to edit something but we do not know *where* the implementation is. If we have the name of a menu, for example we can use it to find every location in the image where the name of the menu is written. 40 | 41 | To do that we need to open a playground and type the text (or select some text in an editor) then select on a right click `Code search...` then `Method source with it`. 42 | 43 | This will open a message browser with all the methods/class comments containing the string of code we are looking for. 44 | 45 | ## Interrupt the Pharo process 46 | 47 | Pharo currently runs in one native thread. If you launch a method taking a lot of time to run, or if you have an infinite loop in your code, you might want to interrupt the process. 48 | 49 | It is possible to do that in Pharo with the shortcut `CMD/ALT + .`. 50 | 51 | > This feature will work in most cases. However, sometimes it might not work, e.g. when faulty code would have taken up too much memory, or when a process is executing outside of the VM (FFI calls). 52 | 53 | ## Debugging facilities 54 | 55 | Pharo includes multiple ways to help with debugging. This section gives some of them. 56 | 57 | `Object` implements multiple debugging messages that are useful. They can be sent to any object in your code: 58 | 59 | - `#halt` : This method will stop the execution of your code when it is called and will open a debugger. (/!\ Do not use it in a code called multiple times in a fork, or system critical loops or you can regret it by breaking your image. In this case, it is advisable to not save your image in this kind of unstable state) 60 | - `#haltOnce` : This method stops the execution and raises a debugger only on the first time it is called. To enable it once more, use `Menubar -> Debbuging -> Enable all break/inspect once`. 61 | - `#haltIf:` : This method takes a block as a parameter. It will stop the execution and open the debugger if the block as parameter returns `true`. 62 | - `#haltOnCount:` : This method takes a number as an argument, it will stop the execution and open the debugger when it will be called at least the number of times given as argument. Reset the counter via `Menubar -> Debbuging -> Reset Counters`. 63 | - `#inspect` : This message can be called on any object and will open an inspector for the receiver. 64 | - `#inspectOnce` : This message works like #haltOnce for inspecting. 65 | 66 | **Example** 67 | 68 | ``` Smalltalk 69 | 70 | myMethod 71 | 72 | | temp | 73 | self doSomething. 74 | 75 | "If you think an infinite loop might happen here, #haltOnCount: might help" 76 | self haltOnCount: 1000. 77 | 78 | temp := self doSomethingElse. 79 | 80 | "Inspect the first value of #temp" 81 | temp inspectOnce. 82 | 83 | "Debug only in certain conditions" 84 | self haltIf: [ temp isKindOf: ObjectIShouldNotGetHere ]. 85 | 86 | 1 to: 1000 do: [ :e | 87 | 88 | "I want to stop only one time here to check something." 89 | self haltOnce. 90 | 91 | self doSomethingWith: e ] 92 | 93 | ``` 94 | 95 | -------------------------------------------------------------------------------- /ExternalProjects/Export/JSON.md: -------------------------------------------------------------------------------- 1 | # JSON support in Pharo 2 | Currently, Pharo provides two main frameworks to handle the [JSON format](https://en.wikipedia.org/wiki/JSON). 3 | 4 | This page briefly present these two frameworks and expose their differences to help users to choose the one fitting their needs. 5 | 6 | - [STONJSON](#stonjson) 7 | * [Parse JSON](#parse-json) 8 | * [Generate JSON](#generate-json) 9 | - [NeoJSON](#neojson) 10 | * [Install](#install) 11 | * [Parse JSON](#parse-json-1) 12 | * [Generate JSON](#generate-json-1) 13 | - [STONJSON v.s. NeoJSON](#stonjson-vs-neojson) 14 | - [JSON Schema](#json-schema) 15 | 16 | ## STONJSON 17 | STONJSON is the built-in JSON parser available in default Pharo images. It is part of the STON package and its development takes place in Pharo's [github repository](https://github.com/pharo-project/pharo). 18 | 19 | ### Parse JSON 20 | - From `String`: 21 | ```Smalltalk 22 | STONJSON fromString: '{ "foo" : 42.0 }' "a Dictionary('foo'->42.0 )" 23 | ``` 24 | 25 | - From `Stream`: 26 | ```Smalltalk 27 | readStream := '{ "foo" : 42.0 }' readStream. 28 | STONJSON fromStream: readStream "a Dictionary('foo'->42.0 )" 29 | ``` 30 | 31 | - Read from JSON file: 32 | ```Smalltalk 33 | '/path/to/file.json' asFileReference 34 | readStreamDo: [ :readStream | 35 | STONJSON fromStream: readStream ] "a Dictionary('foo'->42.0 )" 36 | ``` 37 | 38 | ### Generate JSON 39 | - Let `jsonObject` be defined as: 40 | ```Smalltalk 41 | jsonObject := Dictionary new 42 | at: 'foo' put: 42.0; 43 | yourself. 44 | ``` 45 | 46 | - To generate a JSON `String`: 47 | ```Smalltalk 48 | STONJSON toString: jsonObject "'{""foo"":42.0}'" 49 | ``` 50 | 51 | - To generate JSON on a `Stream`: 52 | ```Smalltalk 53 | STONJSON put: jsonObject onStream: writeStream 54 | ``` 55 | 56 | - To write a JSON file: 57 | ```Smalltalk 58 | '/path/to/file.json' asFileReference 59 | writeStreamDo: [ :writeStream | 60 | STONJSON put: jsonObject onStream: writeStream ] 61 | ``` 62 | 63 | To pretty print JSON, either use `STONJSON>>#toStringPretty:` or `STONJSON>>#put:onStreamPretty:`. 64 | 65 | ## NeoJSON 66 | NeoJSON is actually maintained by Sven Van Caekenberghe on [github](https://github.com/svenvc/NeoJSON). 67 | This section shows some quick examples but there is a great [documentation made by Sven](https://github.com/svenvc/docs/blob/master/neo/neo-json-paper.md) and a chapter in [Enterprise Pharo (chapter 8)](http://books.pharo.org/enterprise-pharo/). 68 | 69 | ### Install 70 | To install NeoJSON, simply execute the following code snippet in a playground: 71 | ``` 72 | Metacello new 73 | repository: 'github://svenvc/NeoJSON/repository'; 74 | baseline: 'NeoJSON'; 75 | load 76 | ``` 77 | 78 | ### Parse JSON 79 | 80 | - From `String`: 81 | ```Smalltalk 82 | NeoJSONReader fromString: '{ "foo" : 42.0 }' "a Dictionary('foo'->42.0 )" 83 | ``` 84 | 85 | - From `Stream`: 86 | ```Smalltalk 87 | readStream := '{ "foo" : 42.0 }' readStream. 88 | (NeoJSONReader on: readStream) next 89 | ``` 90 | 91 | - Read from JSON file: 92 | ```Smalltalk 93 | '/path/to/file.json' asFileReference 94 | readStreamDo: [ :readStream | 95 | (NeoJSONReader on: readStream) next ] "a Dictionary('foo'->42.0 )" 96 | ``` 97 | 98 | ### Generate JSON 99 | Let `jsonObject` be defined as: 100 | ```Smalltalk 101 | jsonObject := Dictionary new 102 | at: 'foo' put: 42.0; 103 | yourself. 104 | ``` 105 | 106 | - To generate a JSON `String`: 107 | ```Smalltalk 108 | NeoJSONWriter toString: jsonObject "'{""foo"":42.0}'" 109 | ``` 110 | 111 | Pretty: 112 | ```Smalltalk 113 | NeoJSONWriter toStringPretty: jsonObject 114 | ``` 115 | 116 | - To generate JSON on a `Stream`: 117 | ```Smalltalk 118 | (NeoJSONWriter on: writeStream) 119 | nextPut: jsonObject 120 | ``` 121 | 122 | Pretty: 123 | ```Smalltalk 124 | (NeoJSONWriter on: writeStream) 125 | prettyPrint: true; 126 | nextPut: jsonObject. 127 | ``` 128 | 129 | - To write a JSON file: 130 | ```Smalltalk 131 | '/path/to/file.json' asFileReference 132 | writeStreamDo: [ :writeStream | 133 | (NeoJSONWriter on: writeStream) 134 | nextPut: jsonObject ] 135 | ``` 136 | 137 | Pretty: 138 | ```Smalltalk 139 | '/path/to/file.json' asFileReference 140 | writeStreamDo: [ :writeStream | 141 | (NeoJSONWriter on: writeStream) 142 | prettyPrint: true; 143 | nextPut: jsonObject ] 144 | ``` 145 | 146 | ## STONJSON v.s. NeoJSON 147 | 148 | |Property |STONJSON |NeoJSON | 149 | |------------------------------------------------|--------------------|----------------------| 150 | |Parse JSON | :white_check_mark: | :white_check_mark: | 151 | |Generate JSON | :white_check_mark: | :white_check_mark: | 152 | |Pretty-printing | :white_check_mark: | :white_check_mark: | 153 | |Built-in | :white_check_mark: | :x: | 154 | |Facilities to map JSON objects to Pharo objects | :x: | :white_check_mark: | 155 | |Facilities to query JSON objects | :x: | :white_check_mark: * | 156 | 157 | > *See [this post](http://forum.world.st/How-to-query-a-JSON-tp4948175p4948177.html) from Sven on the mailing list to know how to use this feature implemented in `NeoJSONObject`. 158 | 159 | ## JSON Schema 160 | JSON Schema allows to describes the structure of JSON objects. It is similar to [XML Schema](https://en.wikipedia.org/wiki/XML_Schema_(W3C)) but for JSON. 161 | 162 | A yet incomplete (but working in its scope) implementation of JSON Schema is provided by Zweidenker [on github](https://github.com/zweidenker/JSONSchema). 163 | -------------------------------------------------------------------------------- /General/MenuBar.md: -------------------------------------------------------------------------------- 1 | # Menubar and World menu 2 | 3 | In Pharo, to open tools or execute actions a Menubar (At the top of the screen) and a WorldMenu (Appears on a left click in the world) are present. 4 | 5 | This page will document some aspects of those features. 6 | 7 | - [Disable the Menubar/WorldMenu](#disable-the-menubarworldmenu) 8 | - [Add your own entries](#add-your-own-entries) 9 | * [Add a simple entry](#add-a-simple-entry) 10 | * [Add a sub menu](#add-a-sub-menu) 11 | - [Change the menu](#change-the-menu) 12 | 13 | ![MenuBar_Image_WhatIsMenuBarAndWorldMenu.png](./MenuBar_Image_WhatIsMenuBarAndWorldMenu.png) 14 | 15 | ## Disable the Menubar/WorldMenu 16 | 17 | In some case, we want to hide the menubar and/or the world menu. For example, when releasing a new version of a project to deploy, the development tools need to be hidden. 18 | 19 | It is possible to do that with some settings. 20 | 21 | **Disable Menubar** 22 | 23 | This option is named `Show menubar` in the setting browser and is equivalent of executing: 24 | 25 | ```Smalltalk 26 | MenubarMorph showMenubar: false 27 | ``` 28 | 29 | **Disable the WorldMenu** 30 | 31 | It is not possible to disable this feature alone (without disabling the Menubar) in Pharo <= 7. 32 | 33 | In Pharo 8 it is possible to disable the WorldMenu alone with the setting named `Show world menu` or by executing: 34 | 35 | ```Smalltalk 36 | PasteUpMorph shouldShowWorldMenu: false 37 | ``` 38 | 39 | **Disable WorldMenu and Menubar** 40 | 41 | To disable both the menubar and the world menu it is possible to disable each of them individually, or to change the setting `World menu pragma` to set an empty pragma. Programmatically, it can be done this way: 42 | 43 | ```Smalltalk 44 | WorldState desktopMenuPragmaKeyword: '' 45 | ``` 46 | 47 | ## Add your own entries 48 | 49 | It is possible to add entries to the world menu and menu bar. 50 | 51 | To build the menu, Pharo uses a pragma mecanism. Each class method containing a pragma `` will be executed with a menu builder as parameter. The method should then configure the builder to add the needed entries. 52 | 53 | ### Add a simple entry 54 | 55 | To add a simple entry, one need to create and configure a new item in the builder. 56 | 57 | Here is a minimal example of a new entry toogling the `Show deprecation warnings` setting: 58 | 59 | ```Smalltalk 60 | MyClass class>>toggleDeprecationWorldMenuOn: aBuilder 61 | 62 | (aBuilder item: #ToggleDeprecation) 63 | action: [ Deprecation raiseWarning: (Deprecation raiseWarning) not ] 64 | ``` 65 | 66 | Then multiple things can be configured. 67 | 68 | - `order:` : Takes a number as parameter and sort the entries with those values from the minimal to the maximal value. 69 | - `help:` : Takes a string as parameter and display at is a tooltip on a long mouse over the menu entry. 70 | - `iconName:` : Takes a symbol as parameter and display an icon correspongding to the name next to the menu entry. (See [this page for more infos](CoolSnippets.md#browse-all-available-icons)) 71 | - `icon:` : Takes a `Form` as parameter and use it to display next to the menu entry. 72 | - `label:` : Takes a string as parameter and replace the display text of the menu entry from the item name to the string. 73 | - `action:` : Takes a block as parameter and execute it when the entry is clicked. 74 | - `withSeparatorAfter` : Add a separator in the UI after this entry. 75 | 76 | ```Smalltalk 77 | toggleDeprecationWorldMenuOn: aBuilder 78 | 79 | (aBuilder item: #ToggleDeprecation) 80 | order: 10; 81 | help: 'Toggle the show deprecation setting'; 82 | iconName: #tools; 83 | label: 'Toggle deprecation'; 84 | action: [ Deprecation raiseWarning: (Deprecation raiseWarning) not ]; 85 | withSeparatorAfter 86 | ``` 87 | 88 | ### Add a sub menu 89 | 90 | It is possible to have submenus in the Menubar. This can be achieve in two ways. 91 | 92 | The first way is to create a new menu and add the children in a `#with:` block. 93 | 94 | Example: 95 | 96 | ```Smalltalk 97 | extensionsWorldMenuOn: aBuilder 98 | 99 | (aBuilder item: #Extensions) 100 | order: 5; 101 | iconName: #add; 102 | with: [ (aBuilder item: #ToggleDeprecation) 103 | order: 10; 104 | help: 'Toggle the show deprecation setting'; 105 | iconName: #tools; 106 | label: 'Toggle deprecation'; 107 | action: [ Deprecation raiseWarning: Deprecation raiseWarning not ]; 108 | withSeparatorAfter ] 109 | ``` 110 | 111 | The second way is to define the submenus in a different place and to use the `#parent:` method to link it to its menu. 112 | 113 | Example: 114 | 115 | ```Smalltalk 116 | extensionsWorldMenuOn: aBuilder 117 | 118 | (aBuilder item: #Extensions) 119 | order: 5; 120 | iconName: #add 121 | ``` 122 | 123 | ```Smalltalk 124 | toggleDeprecationWorldMenuOn: aBuilder 125 | 126 | (aBuilder item: #ToggleDeprecation) 127 | parent: #Extensions; 128 | order: 10; 129 | help: 'Toggle the show deprecation setting'; 130 | iconName: #tools; 131 | label: 'Toggle deprecation'; 132 | action: [ Deprecation raiseWarning: Deprecation raiseWarning not ]; 133 | withSeparatorAfter 134 | ``` 135 | 136 | ## Change the menu 137 | 138 | It is also possible to totally change the Menubar and WorldMenu in case you do not like the current one, or if you want to create a menu for your application. 139 | 140 | In order to do so, you need to define your own pragma to use by executing this code: 141 | 142 | ```Smalltalk 143 | WorldState desktopMenuPragmaKeyword: 'myOwnMenu' 144 | ``` 145 | 146 | Then you can follow the previous section replacing the `` pragma by `` in the examples. 147 | -------------------------------------------------------------------------------- /General/SortingCollections.md: -------------------------------------------------------------------------------- 1 | # Sorting collections 2 | 3 | A common requirement in software engineering is to sort collections. This page provides information on how to sort collections in Pharo. 4 | 5 | - [Sorting API](#sorting-api) 6 | * [Sort a collection](#sort-a-collection) 7 | * [Keep a collection sorted](#keep-a-collection-sorted) 8 | - [Sort functions](#sort-functions) 9 | - [Sorting via a block](#sorting-via-a-block) 10 | 11 | ## Sorting API 12 | 13 | Pharo's Collections come with an API to sort them. In this section, we will present some of it and explain their difference. 14 | 15 | The default sorting implemented on Pharo's collection is a merge sort. Merge sort worst-case complexity is `O(N log N)`. This sorting algorithm usually does only half as many comparisons as heapsort or quicksort. 16 | 17 | ### Sort a collection 18 | 19 | The two main methods to sort a collection are `#sort:` and `#sorted:`. Those two methods are taking a block or a sort function as parameter (those are explained later in this page) and return a collection sorted based on the parameter. 20 | The difference between the two methods is that `#sort:` sort the receiver when the `#sorted:` method sorts a copy of the receiver. 21 | 22 | ```Smalltalk 23 | #(1 2 4 7 3 6 4) sort: #yourself ascending. "#(1 2 3 4 4 6 7) <= This result is the receiver" 24 | #(1 2 4 7 3 6 4) sorted: #yourself ascending. "#(1 2 3 4 4 6 7) <= This result is a copy of the receiver" 25 | ``` 26 | 27 | Those two methods also have an equivalent without argument, `#sort` and `#sorted` that sort the collection using the `#<=` comparison operator. 28 | 29 | The API described here will sort a collection at one point but new elements added to the collection will not be sorted. If you wish to keep a collection sorted, you should use `SortedCollection` as explained in the next section. 30 | 31 | > Warning: If not absolutely needed, one should not use `SortedCollection` because it might impact performances of your software when adding and removing items to the collection. 32 | 33 | ### Keep a collection sorted 34 | 35 | In case you want to keep a collection sorted, you should use a `SortedCollection`. This collection is configured with a sort block or sort function and will sort all new elements added to the collection. 36 | 37 | You can transform a collection into sorted collection using `#asSortedCollection:` or `#asSortedCollection`. 38 | 39 | ```Smalltalk 40 | (#(1 2 4 7 3 6 4) asSortedCollection: #yourself ascending) 41 | add: 2; 42 | yourself "a SortedCollection(1 2 2 3 4 4 6 7)" 43 | ``` 44 | 45 | You can also instantiate yourself the sorted collection: 46 | 47 | ```Smalltalk 48 | (SortedCollection sortUsing: #yourself ascending) 49 | addAll: #(1 2 4 7 3 6 4); 50 | yourself "a SortedCollection(1 2 3 4 4 6 7)" 51 | ``` 52 | 53 | ```Smalltalk 54 | (SortedCollection sortBlock: [ :a :b | a < b ]) 55 | addAll: #(1 2 4 7 3 6 4); 56 | yourself "a SortedCollection(1 2 3 4 4 6 7)" 57 | ``` 58 | 59 | > Note: #sortUsing: was introduced in Pharo 8. In previous versions it is possible to use #sortBlock: for both sort block and sort functions. 60 | 61 | ## Sort functions 62 | 63 | The first way to sort a collection is to use a sort function. A sort function is an object configuring how to sort a collection. They can be created in different ways and can be composed. 64 | 65 | You can create a sort function using a property and a direction: 66 | 67 | ```Smalltalk 68 | #('longstring' 'test' 'test2') sorted: #size ascending. "#('test' 'test2' 'longstring')" 69 | #('longstring' 'test' 'test2') sorted: [ :string | string size ] descending "#('longstring' 'test2' 'test')" 70 | ``` 71 | 72 | ```Smalltalk 73 | #(#(1 2) #(2 3) #(0 0)) sorted: [:sequence | sequence inject: 0 into: [:sum :each | sum + each] ] descending. "#(#(2 3) #(1 2) #(0 0))" 74 | ``` 75 | 76 | You can use 2 arguments blocks, for cases where the function isn't expressible with objects that respond to `<` and `=`. The only catch is that such a function should return true or false, but a collation order instead, values of -1 (for before), 0 (the same) or 1 (to follow). For example: 77 | 78 | ```Smalltalk 79 | | oddBlock | 80 | oddBlock := [ :a :b | a odd = b odd ifTrue: [ 0 ] ifFalse: [ a odd ifTrue: [ -1 ] ifFalse: [ 1 ] ] ]. 81 | #(1 5 1 3 2 7 9 4 6) asSortedCollection: oddBlock descending "a SortedCollection(6 2 4 3 1 7 9 5 1)" 82 | ``` 83 | 84 | Since Pharo 8, it is also possible to express the previous sort function using a property returning a boolean: 85 | 86 | ```Smalltalk 87 | #(1 5 1 3 2 7 9 4 6) asSortedCollection: #odd ascending "a SortedCollection(6 2 4 3 1 7 9 5 1)" 88 | ``` 89 | 90 | In this case, the elements answering `false` will be placed before the elements answering true in the ascending order. This is explained by the fact that the function will sort the booleans according to their bit value (0 or 1). 91 | 92 | > If you wish to use this feature in a version earlier than Pharo 8, you can add this method as an [extension](Extensions.md) of the Boolean class: 93 | 94 | ```Smalltalk 95 | threeWayCompareTo: anotherObject 96 | ^ self asBit threeWayCompareTo: anotherObject asBit 97 | ``` 98 | 99 | Using #undefinedFirst and #undefinedLast it is possible to deal with nil values, moving them first or last. For Example: 100 | 101 | ```Smalltalk 102 | #(a nil z b) sorted: #value ascending undefinedFirst. "#(nil #a #b #z)" 103 | #(a nil z b) sorted: #value ascending undefinedLast. "#(#a #b #z nil)" 104 | ``` 105 | 106 | Finally, you can use a chained sorted function in case you have elements of the same priority in the first sort function. 107 | 108 | In this next example, we sort by size and for elements of same size we sort by alphabetical order: 109 | 110 | ```Smalltalk 111 | #('test' 'toto1' 'test2' 'toto') sorted: #size ascending, #yourself ascending "#('test' 'toto' 'test2' 'toto1')" 112 | ``` 113 | 114 | ## Sorting via a block 115 | 116 | The second way to sort a collection is to use a sort block. A sort block takes two elements of the collection as parameter and should return a boolean describing if the first one should be before the second one. 117 | 118 | ```Smalltalk 119 | #('longstring' 'test' 'test2') sorted: [ :string1 :string2 | string1 size < string2 size ]. "#('test' 'test2' 'longstring')" 120 | ``` 121 | -------------------------------------------------------------------------------- /General/SessionsManagement.md: -------------------------------------------------------------------------------- 1 | # Sessions Management 2 | 3 | * [Description](#description) 4 | * [Quick start](#quick-start) 5 | * [Register a class to the session manager](#register-a-class-to-the-session-manager) 6 | * [Start-up, Shut-down and Saving actions](#start-up--shut-down-and-saving-actions) 7 | * [Checking the start-up and shut-down list](#checking-the-start-up-and-shut-down-list) 8 | 9 | ## Description 10 | 11 | Pharo images have a concept of **Session**. On each image startup the current session is invalidated and a new session is created. A session starts when one open a Pharo image and stop when one close it. A session is also invalidated when saving the image, therefore creating a new session. 12 | It is possible to hook your project to those sessions to perform actions such as executing code at startup, shutdown, image saving... 13 | 14 | ## Quick start 15 | 16 | Here is a quick start to show how to set a class variable to the home folder of a user at startup and removing this value at shut down. 17 | 18 | You need to do those actions in a `#startUp:` method and `#shutDown:` method on the class side of your class. 19 | 20 | ```Smalltalk 21 | MyClass class>>startUp: isImageStarting 22 | isImageStarting 23 | ifTrue: [ MyVariable := FileLocator home asFileReference ] 24 | ``` 25 | 26 | ```Smalltalk 27 | MyClass class>>shutDown: isImageQuitting 28 | isImageQuitting 29 | ifTrue: [ MyVarible := nil ] 30 | ``` 31 | 32 | Then you need to register the class in the `SessionManager` of Pharo. This is usually done in the `#initialize` method (class-side). 33 | 34 | ```Smalltalk 35 | MyClass class>>initialize 36 | SessionManager default registerUserClassNamed: self name. 37 | self startUp: true. "Here we execute it to set up the value while loading the project." 38 | ``` 39 | 40 | ## Register a class to the session manager 41 | 42 | It is possible to register classes to the `SessionManager` of Pharo in order to be able to execute code at start-up, shut-down or when we save a Pharo image. 43 | 44 | The simplest way to do that is to add this in the class initialization method of the class you want to register. 45 | 46 | ```Smalltalk 47 | MyClass class>>initialize 48 | SessionManager default registerUserClassNamed: self name 49 | ``` 50 | 51 | Sometimes, the order of execution of start-up/shut-down actions might matter. To manage this, it is possible to set a priority. 52 | 53 | ```Smalltalk 54 | MyClass class>>initialize 55 | SessionManager default registerUserClassNamed: self name atPriority: 60 56 | ``` 57 | Registered handlers with lower priority will be executed first. 58 | The actions registered using `#registerUserClassNamed:[atPriority:]` will have a low priority in the startup/shutdown list. 59 | It is possible to further refine the priorities using categories. 60 | 61 | The SessionManager has categories. `User` category is one of them. Categories have priority between each others. 62 | By default the system comes with those categories (sorted by priority from the highest to the lowest one): 63 | 64 | - System (`#registerSystemClassNamed:[atPriority:]`): manages system related modules such as FFI, Files, OSEnvironment, ... 65 | - Network (`#registerNetworkClassNamed:[atPriority:]`): manages network related modules such as Zinc or git. 66 | - Graphical User Interface (`#registerUserGUINamed:[atPriority:]`): manages GUI related modules such as events, sensors, morphic, ... 67 | - Tools (`#registerToolClassNamed:[atPriority:]`): manages the tools of Pharo IDE such as Code browser, Spotter, Inspector, ... 68 | - User (`#registerUserClassNamed:[atPriority:]`): for the users to register their projects most of the time. 69 | 70 | > Most of the time, users should use the `User` category. Use the other ones only if you know what you are doing. 71 | 72 | It is possible to create a new category: 73 | 74 | ```Smalltalk 75 | SessionManager default createCategory: aCategoryName. 76 | SessionManager default createCategory: aCategoryName after: anotherCategoryName. 77 | ``` 78 | 79 | > It is not recommanded to register a new category before the System, Network or GUI ones. If you do, be sure of what you are doing. 80 | 81 | Then one can register classes in you new custom category: 82 | 83 | ```Smalltalk 84 | SessionManager default register: (ClassSessionHandler forClassNamed: self name) inCategory: (SessionManager default categoryNamed: 'MyCategory'). 85 | SessionManager default register: (ClassSessionHandler forClassNamed: self name) inCategory: (SessionManager default categoryNamed: 'MyCategory') atPriority: 30. 86 | ``` 87 | 88 | ## Start-up, Shut-down and Saving actions 89 | 90 | Once a class is registered in the `SessionManager`, it is possible to add start-up and shut-down actions that will be executed when we open, close or save an image. 91 | 92 | To register a start-up action, you need to implement a #startUp: method in the class side of your registered class. 93 | This method is called in two situations: when you launch an image and after you save an image. 94 | This method takes a boolean as parameter. The value of this parameter is true when we start the image and false when we save it. 95 | 96 | Example: 97 | 98 | ```Smalltalk 99 | MyClass class>>startUp: isImageStarting 100 | Transcript traceCr: 101 | (isImageStarting 102 | ifTrue: [ 'Image is starting' ] 103 | ifFalse: [ 'Image was saved' ]) 104 | ``` 105 | 106 | To register a shut-down action, you need to implement a #shutDown: method in the class side of your registered class. 107 | This method is called in two situations: when you quit an image and when you save an image. 108 | This method takes a boolean as parameter. The value of this parameter is true when we quit the image and false when we only save it. 109 | 110 | Example: 111 | 112 | ```Smalltalk 113 | MyClass class>>shutDown: isImageQuitting 114 | Transcript traceCr: 115 | (isImageQuitting 116 | ifTrue: [ 'Image is quitting' ] 117 | ifFalse: [ 'Image is been saved' ]) 118 | ``` 119 | 120 | 121 | ## Checking the start-up and shut-down list 122 | 123 | When manipulating sessions, it is sometime interesting to check the current start-up and shut-down lists. 124 | 125 | It is possible to do this this way: 126 | 127 | ```Smalltalk 128 | SessionManager default startupList. 129 | SessionManager default shutdownList. 130 | ``` 131 | 132 | The results of those methods will be sorted by priority. 133 | -------------------------------------------------------------------------------- /General/InterestingsToKnowForBeginners.md: -------------------------------------------------------------------------------- 1 | # Interesting things to know for beginners 2 | 3 | This page will expose different things that might be interesting to know for beginners. Tools, API, shortcuts... 4 | 5 | The goal is to ease the use of Pharo for beginners. 6 | 7 | - [API](#api) 8 | - [Evaluatable objects (Blocks and Symbols)](#evaluatable-objects--blocks-and-symbols-) 9 | - [Tools](#tools) 10 | * [Calypso System Browser](#calypso) 11 | - [Flags](#flags) 12 | - [Useful pragmas](#useful-pragmas) 13 | * [Modify IDE](#modify-ide) 14 | * [Influence execution of methods](#influence-execution-of-methods) 15 | * [Influence Debugger](#influence-debugger) 16 | 17 | ## API 18 | 19 | The Pharo API is extensive. In this section we will explain various methods existing in Pharo that have proven to be useful in our experience. 20 | 21 | **String class>>#streamContents:** 22 | 23 | String concatenation can be costly because it will create a new string instance and copy the content of the two strings at each concatenation. To make it more efficient, Pharo includes a method to create a String via a stream: 24 | 25 | ```Smalltalk 26 | 'This is a ', 'string concatenation ' , 'that is not really' , ' ' , ' efficient'. 27 | 28 | String streamContents: [ :aStream | aStream << 'This is a '<< 'string concatenation ' << 'that is ' << ' ' << ' efficient' ] 29 | ``` 30 | 31 | ## Evaluatable objects (Blocks and Symbols) 32 | Pharo's Blocks and Symbols have an interesting property: they are polymorphic through `#value:` and `#cull:` methods. 33 | 34 | For example, the two code snippets below are equivalent: 35 | 36 | ```Smalltalk 37 | #class value: Object new 38 | ``` 39 | 40 | ``` 41 | [ :o | o class ] value: Object new 42 | ``` 43 | 44 | They both return the class of an object. 45 | 46 | This means that for methods taking a one-argument block as a parameter, this block can be replaced by a symbol. The effect is that the unary method named by the symbol will be executed with the object as the receiver. 47 | 48 | The difference between `#value:` and `#cull:` is that `#value:` requires a parameter when `#cull:` can work with or without a parameter. 49 | 50 | The common usage of this feature is via iterators. For example, if you want to collect the result of the `name` method of all objects in a collection you can either do: 51 | 52 | ``` 53 | objectCollection collect: [ :o | o name ]. 54 | ``` 55 | 56 | or 57 | 58 | ``` 59 | objectCollecton collect: #name 60 | ``` 61 | 62 | The second way is shorter and often more readable. 63 | 64 | ## Tools 65 | 66 | ### Calypso (System browser) 67 | 68 | - Display the differences between two methods 69 | * Click on a method 70 | * Hold down the `SHIFT` key 71 | * Click on the second method 72 | * Click on the tab Diff to see the differences 73 | 74 | - Editing multiple methods side by side 75 | * Click on a method 76 | * Hold down the `CTRL` key 77 | * Click on all the methods you want to edit. 78 | * Tabs are displayed with the source code of the methods selected. 79 | 80 | ## Flags 81 | 82 | It is possible to "flag" methods in Pharo in order to be able to retrieve them later. This can be done by sending the `#flag:` message to self with a symbol as parameter which is the flag to be used. 83 | 84 | Commonly used flags are: 85 | - `#todo` to mark code that needs work to be done. 86 | - `#hack` to mark hackish code. 87 | - `#broken` to mark broken code. 88 | - `#clean` to mark code that needs cleaning. 89 | - `#toCheck` to mark code that should be checked later. 90 | - `#pharoX` to mark code present for compatibility with `X` being the version of Pharo. 91 | 92 | Flags will not modify the execution of a method. Flags are just used to tag methods. 93 | 94 | For example, the method below will return `42` if executed as if there was no call to `#flag:` method. 95 | 96 | ``` 97 | myUnfinishedMethod 98 | self flag: #TODO. "Some process to be done here." 99 | ^ 42 100 | ``` 101 | 102 | To retrieve methods for which you set flag(s), just search for senders of your flag. For example, to retrieve methods flagged with `#todo`, either inspect the result of the following script: `#todo senders` or just select the symbol and press Meta+N (shortcut for "Browse senders"). 103 | 104 | ## Useful pragmas 105 | 106 | Pragmas allow one to tag methods. They are similar to Java's annotations. Some pragmas allow the developer to modify the IDE or to influence execution of methods. This section presents some of these useful pragmas. 107 | 108 | ### Modify IDE 109 | 110 | - `