我理解Perl代码中的这些特殊函数,BEGIN和CHECK块在编译阶段运行,而INIT和END块在实际执行阶段运行。
我可以理解在实际的Perl代码(Perl库)中使用这些块但是在模块中使用它们呢?这可能吗?
因为当我们使用use <Module-name>
编译模块时,所以实际上BEGIN和CHECK块运行。但是INIT和END块如何运行,因为模块代码我不认为是真正意义上运行的。我们只使用模块内部的某些功能。
答案 0 :(得分:6)
短通过use
加载的软件包中的特殊代码块按照与main::
相同的方式和顺序进行处理和运行(或计划运行) ,因为use
本身就是BEGIN
块。
可以找到关于此的优秀文档in perlmod
。从这一节
BEGIN代码块尽快执行,也就是说,即使在解析包含文件(或字符串)的其余部分之前,它也是完全定义的。
由于use
语句是 BEGIN
阻止,它们会在遇到后立即运行。来自use
完全等同于
BEGIN { require Module; Module->import( LIST ); }
所以包中的BEGIN
块与其他块一起运行,因为遇到它们。然后,包中的END
块也以相同的顺序编译,以及其他特殊块。至于(最终)执行的顺序, END
代码块尽可能晚地执行...... 和
文件中可能有多个END块 - 它们将按定义的相反顺序执行;那就是:后进先出(LIFO)
INIT
和CHECK
块的编译和执行顺序也随之而来。
以下是一些代码,用于演示包中使用的这些特殊代码块。
文件 PackageBlocks.pm
package PackageBlocks;
use warnings;
BEGIN { print "BEGIN block in the package\n" }
INIT { print "INIT block in the package\n" }
END { print "END block in the package\n" }
1;
主要脚本
use warnings;
BEGIN { print "BEGIN in main script.\n" }
print "Running in the main.\n";
INIT { print "INIT in main script.\n" }
use PackageBlocks;
END { print "END in main script.\n" }
BEGIN { print "BEGIN in main script, after package is loaded.\n" }
print "After use PackageBlocks.\n";
输出
BEGIN in main script. BEGIN block in the package BEGIN in main script, after package is loaded. INIT in main script. INIT block in the package Running in the main. After use PackageBlocks. END in main script. END block in the package
包中的BEGIN
块按照出现的顺序运行,与main::
中的INIT
和END
之前的块进行比较。 main::
块在结束时运行,
并且包中的那个在use
中的那个之后运行,因为在此示例中public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"All","Index","Favourite"};
int Numboftabs =3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
if (pager != null) {
pager.setAdapter(adapter);
}
// Assigning the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
if (tabs != null) {
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
}
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
@Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
tabs.setViewPager(pager);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
SearchManager SManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
android.support.v7.widget.SearchView searchViewAction = (android.support.v7.widget.SearchView) MenuItemCompat.getActionView(searchMenuItem); searchViewAction.setSearchableInfo(SManager.getSearchableInfo(getComponentName()));
searchViewAction.setIconifiedByDefault(true);
return true;
}
位于它之前。
答案 1 :(得分:1)
这很容易为自己测试
use Module
(以及require EXPR
和do EXPR
以及eval EXPR
)编译Perl代码,然后立即运行
这是大多数模块末尾的1;
被拾取的地方。如果在编译后执行模块的代码并不返回 true 值,则require
将失败
不可否认,INIT
或END
块通常没有多大用处,因为运行时阶段与编译紧密相关,并且因为模块通常是关于定义子例程,但如果你想要它,那么选项就在那里