0%

以往写法

在以往的 PHP 版本中,我们使用匿名函数的方式可能会显得非常冗长,即使里面只是一个简单的返回,或者一个简单的表达式。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$students = [
[
'name' => 'Foo',
'age' => 20,
],
[
'name' => 'Bar',
'age' => 21,
],
];

$names = array_map(function ($student) {
return $student['name'];
}, $students);

写过 ES6 或者 Java8 的朋友应该对箭头函数这种写法比较熟悉,对比一下:

ES6

1
let names = students.map(student => student.name)

JAVA8 则类似下面的 map 那样

1
2
3
students.stream()
.map(student -> student.name)
.collect(Collectors.toList())

相对比之下,php 就显得有些啰嗦,如果闭包函数里面需要使用外部变量,则还需要把每一个外部变量写到 use 里面,那就会更加冗长。

箭头函数 hello world

现在我们使用箭头函数来重写一下上面的 array_map 调用:

1
2
$names = array_map(fn ($student) => $student['name'], $students);
var_dump($names);

在线运行以上代码: php74-playground

怎么样?是不是简洁又清晰,看起来特别舒服。 functionreturnuse 这些全都不用写了。

同时,如果需要使用外部的变量,再也不需要使用 use 来引入那些外部变量了,在箭头函数后面的表达式直接可以使用:

1
2
3
$y = 10;
$fn = fn ($x) => $x + $y;
var_dump($fn(20)); // 30

在线运行以上代码: php74-playground

旧的写法:

1
2
3
4
5
$y = 10;
$fn = function ($x) use ($y) {
return $x + $y;
};
var_dump($fn(20)); // 30

箭头函数写法

基本形式

1
fn (parameter_list) => expr

简单说一下(但是很重要):

  • fn 是箭头函数标识,原来的 function 关键字在箭头函数里只需写 fn
  • (parameter_list) 是箭头函数的参数列表,fn 和 括号不能省略
  • expr 这个名字已经说明了一切,这里我们只能写一个表达式,不能写多个语句,不接受语句块。
  • expr 是一个表达式,同时也是这个箭头函数的返回值,原来的 return 不用写了

有人会说,为什么还要写 fn,直接 parameter => expr 不就好了吗?

这是因为这种写法已经用于 PHP 的关联数组里面了,冲突了。

想了解为什么的可以看 rfc/arrow_functions_v2

函数签名

  • fn (array $x) => $x;,参数类型限定
  • fn (): int => $x;,返回值类型限定
  • fn ($x = 42) => $x;,参数默认值
  • fn (&$x) => $x;,参数引用传递
  • fn &($x) => $x;,返回值引用
  • fn ($x, ...$rest) => $rest;

总的来说:

参数传递、参数类型限定、返回值类型限定、引用参数传递、返回值引用等写法和旧的写法一致。

不一样的是:

  • 没有了 functionreturnuse 等关键字,也没有了大括号

  • 需要注意的是:不支持大括号,不像 ES6

    • 错误写法:fn (array $x) => {return $x;};

兼容性问题

  • 从 PHP 7.4 起,因为引入了 fn 关键字作为箭头函数的语法,因此,如果你的代码里面有 fn 命名的函数,可能会有冲突。

总结

  • 基本语法 fn (parameter_list) => expr

  • PHP7.4 的箭头函数只支持简单的表达式(只能写一个表达式),不能使用大括号把表达式括起来

想尝鲜的可以在 php74-playground 尝试一下!基于 PHP 7.4.0RC1 版本。

基于 ubuntu 14.04

安装 schroot

1
2
apt-get update
apt-get install schroot

schroot 允许用户在一个 chroot 环境中允许命令

安装 debootstrap

1
apt-get install debootstrap

debootstrap 是 Debian 系列系统下安装系统到子目录的一个工具。我们的 root jail 需要这个工具把系统的一些基本的东西安装都 root jail 目录下。

创建 root jail 目录

1
mkdir /var/jail

修改 schroot 配置文件

trusty 是 ubuntu 版本代号,对应是 ubuntu 14.04

1
2
3
4
5
6
7
[trusty]
description=Ubuntu precise
location=/var/jail
priority=3
users=devops
groups=devops
root-groups=root

安装

1
debootstrap trusty /var/jail/ http://mirrors.163.com/ubuntu/

最后的 http://mirrors.163.com/ubuntu/ 是镜像地址

测试

1
chroot /var/jail

从 root jail 退出

1
exit

后续设置

1
mount -o bind /proc /var/jail/proc

这个操作可以让我们在 root jail 中运行 ps 等命令

基本格式

1
tell application <application name> to <verb> <do something>

可用动词

  • get 用来访问窗口属性

  • set 用来设置窗口属性

  • open 打开窗口

  • close 关闭窗口

  • select 把选中窗口置顶

  1. 获取 Finder 最顶层窗口的标题
1
tell application "Finder" to get the name of the front Finder window
  1. 关闭 Finder 顶层窗口(其他应用类似)
1
tell application "Finder" to close the front window
  1. 打开用户主目录
1
tell application "Finder" to open home
  1. 打开启动盘
1
tell application "Finder" to open the startup disk
  1. 获取 Finder 窗口的索引

当打开了多个 Finder 窗口的时候,可以通过索引来获取对应的 Finder 窗口

1
tell application "Finder" to get index of home

这里假设是 1,下面的命令将会获取用户主目录窗口的标题

1
tell application "Finder" to get the name of window 1
  1. 获取第一个窗口的索引
1
tell application "Finder" to get the index of the first window -- 1

1
tell application "Finder" to get the index of the 1st window
  1. 获取第二个窗口的索引
1
tell application "Finder" to get the index of the second window -- 2

1
tell application "Finder" to get the index of the 2nd window
  1. 根据相对位置获取窗口索引
1
2
3
4
5
6
7
8
9
10
tell application "Finder" to get the front window
--> returns: 1
tell application "Finder" to get the back window
--> returns: 2
tell application "Finder" to get the last window
--> returns: 2
tell application "Finder" to get the index of the Finder window before the last Finder window
--> returns: 1
tell application "Finder" to get the index of the Finder window after the front Finder window
--> returns: 2
  1. 设置窗口索引(改变窗口层叠顺序)
1
tell application "Finder" to set the index of the last window to 1 -- 最底层窗口置顶

获取窗口索引方法

  • 通过窗口名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
by name:
Finder window "Documents"
by numeric index:
Finder window 1
by descriptive index:
the first Finder window
the second Finder window
the fifth Finder window
the 1st Finder window
the 23rd Finder window
by relative position index:
the front Finder window
the middle Finder window
the back Finder window
the last Finder window
by random index:
some Finder window
  1. 设置 Finder 顶层窗口到某一个目录

这里是 ~/Code

1
tell application "Finder" to set the target of the front Finder window to folder "Code" of home
1
tell application "Finder" to set the target of the front Finder window to the startup disk

多级目录

1
tell application "Finder" to set the target of the front Finder window to folder "Smith Project" of folder "Documents" of home
  1. 显示、隐藏 Finder 工具栏
1
tell application "Finder" to set toolbar visible of the front window to false -- 隐藏
1
tell application "Finder" to set toolbar visible of the front window to true -- 显示
  1. 显示、隐藏 Finder 状态栏
1
2
tell application "Finder" to set statusbar visible of Finder window 1 to true -- 显示
tell application "Finder" to set statusbar visible of Finder window 1 to false -- 隐藏
  1. 设置侧边栏宽度
1
2
3
tell application "Finder" to set the sidebar width of Finder window 1 to 200 -- 设置顶层窗口
tell application "Finder" to set the sidebar width of the second Finder window to 240 -- 设置第二个窗口
tell application "Finder" to set the sidebar width of every Finder window to 0 -- 隐藏所有 Finder 窗口的侧边栏
  1. Finder view 属性设置
1
2
3
4
5
6
7
8
9
10
tell application "Finder" to get the current view of the front Finder window -- 获取当前 view 属性 (list view, column view, flow view, icon view)

tell application "Finder" to set the current view of the front Finder window to list view

tell application "Finder" to set the current view of the front Finder window to column view

tell application "Finder" to set the current view of the front Finder window to flow view
--> flow view is new in Mac OS X v10.5 (Leopard)

tell application "Finder" to set the current view of the front Finder window to icon view
  1. 获取顶部 Finder 窗口的位置
1
tell application "Finder" to get the position of the front window
  1. 设置 Finder 窗口的位置
1
tell application "Finder" to set the position of the front window to {0, 300}
  1. 获取窗口边界距离屏幕边缘的距离
1
2
tell application "Finder" to get the bounds of the front window
--> returns something like: {72, 90, 512, 481}

各数字意义:

72: 距离屏幕左边边缘的距离

90: 距离屏幕顶部边缘的距离

512: 距离屏幕右边边缘的距离

481: 距离屏幕底部边缘的距离

  1. 置顶窗口
1
tell application "Finder" to select the last Finder window -- 置顶最底部窗口
1
tell application "Finder" to set the index of the last Finder window to 1
  1. tell 语句块

不用每一个语句都写 tell application "xxx"

1
2
3
4
5
6
7
8
9
10
11
12
13
tell application "Finder"
close every window
open home
set toolbar visible of the front Finder window to true
set the sidebar width of the front window to 135
set the current view of the front window to column view
set the bounds of the front Finder window to {36, 116, 511, 674}
open folder "Documents" of home
set toolbar visible of the front Finder window to false
set the current view of the front Finder window to flow view
set the bounds of front Finder window to {528, 116, 1016, 674}
select the last Finder window
end tell
  1. 嵌套 tell 语句块

在对某一个窗口对象操作的时候,可以独立写一个 tell 语句块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tell application "Finder"
close every window

open home
tell the front Finder window
set toolbar visible to true
set the sidebar width to 135
set the current view to column view
set the bounds to {36, 116, 511, 674}
end tell

open folder "Documents" of home
tell the front Finder window
set toolbar visible to false
set the current view to flow view
set the bounds to {528, 116, 1016, 674}
end tell

select the last Finder window
end tell
  1. 激活窗口
1
2
3
tell application "Wechat"
activate
end tell
  1. 置顶
1
2
3
tell application "Wechat"
set frontmost to true
end tell
  1. 取消最小化
1
2
3
4
5
tell application "Wechat"
try
set miniaturized of windows to false
end try
end tell
  1. 日志输出
1
log "a" -- 可以在 script editor 底部的 events 查看
log.png
  1. 遍历 UI 元素

every group --> Returns a list of groups. every UI element of every group --> Returns a list of lists (corresponding to groups) of UI elements. every button of every UI element of every group --> Returns a list of lists (corresponding to groups) of lists (corresponding to UI elements) of button references.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tell application "Safari"
activate
end tell

tell application "System Events"
tell process "Safari"
tell window 1
tell toolbar 1
set theButtons to every button of every UI element of every group
repeat with i in theButtons
try
tell (first button whose description is "Translate")
perform action "AXPress"
end tell
end try
end repeat
end tell
end tell
end tell
end tell
  1. 获取当前窗口所有的 UI 元素
1
2
3
4
5
6
7
tell application "System Events"
tell process "Capture One 20"
tell window 1
set uiElems to entire contents
end tell
end tell
end tell

一个实际的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
tell application "Capture One 20"
activate
end tell

-- 等待 element 这个 UI 元素就绪,超时退出脚本,并提示错误
on ready(element, waitReady)
set t to 5 -- 超时时间
set elapsed to 0
repeat while true
if waitReady then
if element exists then
log elapsed
return
end if
end if

if not waitReady then
if not (element exists) then
log elapsed
return
end if
end if

delay 0.1

set elapsed to elapsed + 0.1
if elapsed > t then
display notification "操作超时" with title "AppleScript错误"
error number -128
end if
end repeat
end ready

tell application "System Events"
tell process "Capture One 20"
-- 遍历查找对应的 window
global win
set win to 0
repeat with w in windows
if exists of radio button 2 of radio group 1 of w then
set win to w
end if
end repeat

if win = 0 then
display notification "无法获取有效窗口" with title "AppleScript错误"
return
end if

-- 点击相机图标
click radio button 2 of radio group 1 of win
delay 0.1

global destination
set destination to 0

-- 遍历检查 group 里面是否有 scroll area 2 -> "NextCaptureLocation" -> "目的地"
repeat with g in every group of win

-- 遍历每一个 scroll area,找到包含 "NextCaptureLocation" 的那一个,最终找到 destination
repeat with sa in every scroll area of g
if exists of group "NextCaptureLocation" of sa then
set nextCaptureLocation to group "NextCaptureLocation" of sa

-- 中文版
if exists of group "目的地" of nextCaptureLocation then
set destination to group "目的地" of nextCaptureLocation
exit repeat -- 退出循环
end if

-- 英文版
if exists of group "Destination" of nextCaptureLocation then
set destination to group "Destination" of nextCaptureLocation
exit repeat -- 退出循环
end if
end if
end repeat

end repeat

-- 判断 destination 是否获取到,没有获取到则提示并退出 applescript
if destination = 0 then
display notification "无法获取目标元素 Destination" with title "AppleScript错误"
return
end if

-- 点击选择文件夹,并设置为自定义的文件夹
click pop up button 1 of destination
my ready(menu item -1 of menu 1 of pop up button 1 of destination, true)
click menu item -1 of menu 1 of pop up button 1 of destination

-- delay 1
my ready(sheet 1 of win, true) -- sheet 1 是 Finder 弹窗
-- Finder 里面 shift + command + G 可以自己手动输入路径
key code 5 using {shift down, command down}

-- 等待弹出输入框后再进行下一步
my ready(text field 1 of sheet 1 of win, true)

-- 清空弹出文本域的内容
key code 0 using {command down} -- command + A
key code 51 -- 51 对应回车键

-- 输入自定义的路径
set the clipboard to "/tmp"
-- keystroke "/tmp"
-- 输入法会影响,所以使用粘贴的方式
key code 9 using {command down} -- command + v

-- 按下回车,等待输入框消失
keystroke return
-- 中文版
if button "前往" of sheet 1 of win exists then
my ready(button "前往" of sheet 1 of win, false)
end if
-- 英文版
if button "Go" of sheet 1 of win exists then
my ready(button "Go" of sheet 1 of win, false)
end if

keystroke return

end tell
end tell

安装指引

这里假设要安装 gitlab-ce 10.3.3

先在 https://packages.gitlab.com/gitlab/gitlab-ce 找到对应版本的 gitlab-ce

gitlab-ce-10.3.3-ce.0.el7.x86_64.rpm

安装

1
curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
1
sudo yum install gitlab-ce-10.3.3-ce.0.el7.x86_64

启动

1
gitlab-ctl start

配置 gitlab 域名和端口

修改 /etc/gitlab/gitlab.rb,如

1
external_url 'http://gitlab.local:8888'

修改配置之后,需要运行:

1
gitlab-ctl reconfigure

查看安装信息

打开 http://gitlab.local:8888/help