Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby-扩展Ruby中的内置变量_Ruby_Oop_Types_Metaprogramming - Fatal编程技术网

Ruby-扩展Ruby中的内置变量

Ruby-扩展Ruby中的内置变量,ruby,oop,types,metaprogramming,Ruby,Oop,Types,Metaprogramming,我想在Ruby中扩展变量的功能。原因是我正在研究类似于类型系统或值检查器的东西(这听起来有点疯狂,但整个想法很难解释,这正是我想要扩展默认变量的原因) 我在Ruby中读到过,一切都是一个对象;所以变量就是对象。Ruby对于通过元编程可以改变什么应该是相当自由的 是否有某种与局部变量相关的“类”可以扩展 我想为每个保存类型的字符串表示的变量关联一个字符串变量。此外,我想截取变量赋值,并在每次给变量赋值时执行一个方法。这样我就可以根据类型(存储为变量中的字符串)检查新值是否正确 如果Ruby中的局部

我想在Ruby中扩展变量的功能。原因是我正在研究类似于类型系统或值检查器的东西(这听起来有点疯狂,但整个想法很难解释,这正是我想要扩展默认变量的原因)

我在Ruby中读到过,一切都是一个对象;所以变量就是对象。Ruby对于通过元编程可以改变什么应该是相当自由的

是否有某种与局部变量相关的“类”可以扩展

我想为每个保存类型的字符串表示的变量关联一个字符串变量。此外,我想截取变量赋值,并在每次给变量赋值时执行一个方法。这样我就可以根据类型(存储为变量中的字符串)检查新值是否正确

如果Ruby中的局部变量被定义为类的对象,我可以扩展该类或通过Ruby mixin修改它

解决方法是为我的变量创建一个新类(而不是使用Ruby的内置局部变量)。这个类可以有一个value属性、一个type属性(存储为string)和一个get-and-set方法。这样我可以解决我的问题,但如果可能的话,我想扩展ruby中的内置变量

当前正在进行的工作

class Fixnum
        attr_accessor :tp
        @tp

        def mytype ( type )
                @tp = type
        end
        def typecheck
                #call typechecker
                puts "checked"
        end
end
测试代码:

a = 3
a.mytype("nat")
puts a.tp
a.typecheck
还有两个问题。 首先,我认为不可能向Fixnum添加新的构造函数。其次,我想截取变量访问,即“b=a”调用a的方法“typecheck”。但这需要类似于面向方面编程的东西,我不确定是否可以用Ruby的元编程工具解决这个问题

我在Ruby中读到过,一切都是一个对象

这取决于你对“对象”和所有“事物”的定义。“对象”可以是指“可由程序操作的实体”(从现在起我将称之为对象),或“作为对象系统成员的值”(从现在起我将称之为
对象

在Ruby中,程序可以操作的所有东西(即每个对象)也是一个
对象
,即一个类的实例。这与Java不同,例如,在Java中,原语可以由程序操作(即在这个词的意义上是对象),但不是
对象
。在Ruby中,这种区别并不存在:每个对象都是
对象,每个
对象也都是对象

然而,语言中有些东西不能被程序操纵,也不是类的实例,即它们既不是对象s,也不是
对象
s。例如,这些是方法、变量、语法、参数列表、参数列表、关键字

注意:您可以使用Ruby的反射API为您提供一个表示方法或参数列表的对象,但该对象只是一个代理,不是真正的对象

因此,当我们说“一切都是对象”时,我们真正的意思是“每个对象都是
对象
”,也就是说,程序可以操纵的一切都是对象系统的成员,或者换句话说,对象系统之外没有任何值(与Java中的原语不同)。我们并不意味着语言中存在的所有东西都可以在运行时被程序操纵

所以变量就是对象

不,不幸的是,它们既不是对象s,也不是
对象
s

Ruby语言规范中也明确说明了这一点(我添加了重点):

6.2变量 6.2.1一般说明 变量由名称表示,表示对象,称为变量值。 变量本身不是对象

书中第2页写道:

每个值都是一个对象

注意,它并不是说每件事,只是说每一个值

另见问题

我在Ruby中读到过,一切都是一个对象

这取决于你对“对象”和所有“事物”的定义。“对象”可以是指“可由程序操作的实体”(从现在起我将称之为对象),或“作为对象系统成员的值”(从现在起我将称之为
对象

在Ruby中,程序可以操作的所有东西(即每个对象)也是一个
对象
,即一个类的实例。这与Java不同,例如,在Java中,原语可以由程序操作(即在这个词的意义上是对象),但不是
对象
。在Ruby中,这种区别并不存在:每个对象都是
对象,每个
对象也都是对象

然而,语言中有些东西不能被程序操纵,也不是类的实例,即它们既不是对象s,也不是
对象
s。例如,这些是方法、变量、语法、参数列表、参数列表、关键字

注意:您可以使用Ruby的反射API为您提供一个表示方法或参数列表的对象,但该对象只是一个代理,不是真正的对象

因此,当我们说“一切都是对象”时,我们真正的意思是“每个对象都是
对象
”,也就是说,程序可以操纵的一切都是对象系统的成员,或者换句话说,对象系统之外没有任何值(与Java中的原语不同)。我们并不意味着语言中存在的所有内容都可以在运行时b中进行操作
class Array
  def to_s
    return "An array of size #{self.size}."
  end
end

a = [1, 2, 3, 4]
puts a.to_s
# => "An array of size 4."
class MyClass
  # Use the default getter for var.
  attr_reader :var      

  def initialize
    @var = 1
  end

  # Custom setter for var.
  def var= v
    @var = v
    puts "var changed to #{v}"
  end
end

mc = MyClass.new
mc.var = 9
# => "var chaged to 9"
$type_checked = {:$a => String, :$b => Array}
$type_checked.keys.each do |var|
  trace_var(var) do |obj|
    puts "hey, don't assign #{var} to a #{obj.class}" unless $type_checked[var] == obj.class
    #or raise an Error
  end
end

$a = 1
$a = "a"
$b = 1

#output:
#hey, don't assign $a to a Fixnum
#hey, don't assign $b to a Fixnum